2015-07-19 22 views
5

szukam jakiejś pomocy potokiem plik (16-bitowa mały endian liczby całkowite dane surowe) z linii komend do mojego programu:Rurociągi plik danych z kotem do C++ programu

cat data.dat | myprogram 

Następnie powinien przekonwertować dane na 16-bitowe liczby całkowite ze znakiem. Działa dla pierwszych 12 wartości. 13. wartość jest błędna, a następnie zera.

Drugi problem polega na tym, że program wydaje się wchodzić w pętlę while tylko raz.

Używam Windows + MinGW.

mój kod:

#include <iostream> 
using namespace std; 

#define DEFAULT_BUF_LENGTH (16 * 16384) 

int main(int argc, char* argv[]) 
{ 
    char buf[DEFAULT_BUF_LENGTH]; 

    while(cin >> buf) 
    { 
     int16_t* data = (int16_t*) buf; //to int 

     for(int i=0;i<18;i++) 
     { 
      cout << data[i] << endl; 
     } 
    } 
    return 0; 
} 

wyjścia:

0 
9621 
-14633 
-264 
5565 
-12288 
9527 
-7109 
11710 
6351 
4096 
-5033 
5773 
147 
0 
0 
0 
0 

Dzięki za pomoc!

+0

możliwe duplikat [orurowanie dla wejścia/wyjścia] (http://stackoverflow.com/questions/17508626/piping-for-input-output) –

+0

Sprawdź [this] (http://stackoverflow.com/a/1599093/4074081) dyskusja. W systemie Windows stdin jest otwierany w trybie tekstowym, a określony bajt wskazuje koniec pliku, rozwiązaniem jest ponowne otwarcie go w trybie binarnym. – dewaffled

+0

Nie można użyć '>>' konwertuje zakończenia linii. Musisz użyć ** niesformatowanych wejściowych ** funkcji, takich jak 'cin.read()'. http://en.cppreference.com/w/cpp/io/basic_istream – Galik

Odpowiedz

4

Można spróbować użyć read() zamiast operatora >>, która jest na ogół dla wejścia sformatowana. Również sprawdzenie, ile danych zostało właściwie odczytać jest przydatna:

#include <iostream> 
using namespace std; 

#define DEFAULT_BUF_LENGTH (16 * 16384) 

int main(int argc, char* argv[]) 
{ 
    char buf[DEFAULT_BUF_LENGTH]; 

    for(;;) 
    { 
     cin.read(buf, sizeof(buf)); 
     int size = cin.gcount(); 
     if (size == 0) break; 

     int16_t* data = (int16_t*) buf; //to int 

     for(int i=0;i<size/sizeof(int16_t);i++) 
     { 
      cout << hex << data[i] << endl; 
     } 
    } 
    return 0; 
} 
+0

Drugi problem nadal występuje, program wypisuje tylko pierwsze 12 wartości. Zapomniałem wspomnieć, że kompiluję moje programy za pomocą 'g ++ myprogram.cpp -static -o myprogram'. Być może to jest powód? Jeśli skompiluję mój program bez flagi -static, ulegnie on awarii po wykonaniu (APPCRASH: Error Module Name: libstdC++ - 6.dll). Nie znalazłem rozwiązania tego problemu, ale myślę, że ma coś wspólnego z 64-bitowym systemem Windows. W systemie Linux Twój kod działa zgodnie z oczekiwaniami. – fuxT

+0

Przydałby się twój plik wejściowy –

+0

Nawet prosty program helloworld.cpp ulega awarii, jeśli nie ustawię flagi '-static'. Myślę, że mój MinGW jest zepsuty. Mój problem jest podobny do tego: [http://stackoverflow.com/questions/18157464/c-helloworld-program-compiled-with-mingw-crashes-with-lub-argument-argument] ale nie ma "libstdC++. Dll" w 'windows \ syswow64', które mogłem usunąć ... – fuxT

1

Oświadczenie cin >> buf ma nie wypełnić cały buf z danymi. Czyta tylko następny "zestaw" znaków spoza białych znaków. Zmień cin >> buf do read(0, buf, sizeof(buf)) > 0

Jeśli upierasz się przy użyciu strumieni C++ zmienić początku swojej pętli:

while (!cin.eof()) { 
    cin.read(buf, sizeof(buf)); 
    [...] 
+1

Zgadzam się z diagnozą; to jest problem. Nie jestem przekonany, że proponowane lekarstwo jest najlepszą opcją. Z pewnością istnieją sposoby odczytywania danych binarnych z 'cin' zamiast cofania się do funkcji deskryptorów plików POSIX, takich jak' read() ', które również wymagają nagłówka' '. –

+0

@ JonathanLeffler: Cóż, czasami użycie "dobrego C" jest prostsze;) – nsilent22