2012-03-05 4 views
1

Мне было интересно .. как вы читаете байты по одному из двоичного файла? В качестве примера я хотел бы читать байты по одному из некоторого двоичного файла, а затем записывать эти точные байты в некоторый выходной файл (в основном, очень простая реализация команды cp). Мой текущий код C выглядит следующим образом:Чтение «чистых» байтов в C

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char**argv) 
{ 
    if (argc != 2) { 
     fprintf(stderr, "Usage: %s <output file>\n", argv[0]); 
     return 1; 
    } 

    FILE *outfile; 
    outfile = fopen(argv[1], "w"); 

    unsigned char c; 
    char temp; 
    int tracker = 0; 
    // Use temp because unsigned char will never be EOF 
    while ((temp = getchar()) != EOF) { 
     c = (unsigned char) temp; 
     fprintf(outfile, "%c", c); 
    } 
fclose(outfile); 
return 0; 
} 

я запустить программу, как это: ./main output.au < sample.au (.au это звуковой файл)

Однако, все это я получаю в файле output.au является связка «^ @ "повторяется снова и снова. Я могу воспроизвести аудиофайл sample.au, но не output.au. Я также (несколько бессмысленно) сделал diff по двум файлам, и, как и ожидалось, они выходят по-другому.

Помощь? Спасибо! -kstruct

UPDATE Спасибо за ответ все .. мой код теперь выглядит следующим образом:

outfile = fopen(argv[1], "wb"); 

int c; 
while ((c = getchar()) != EOF) { 
    fprintf(outfile, "%c", c); 
} 
+0

Обычно вы должны читать/записывать блоки «чистых» байтов в C, а не в один байтовый подход. – perreal

+0

@kstruct Ваш обновленный код работает для меня. – ibid

ответ

7

getchar() возвращает int. Вы назначаете int переменной типа char, тем самым теряя информацию. Не делайте этого.

Объявление temp как int, и избавиться от актеров.

+0

Я вижу, имеет смысл, я согласен со всем. Однако у меня все еще есть проблема. Мой обновленный код выше. Помогите? Благодаря! – adelbertc

+0

Просто шучу, что это работает - спасибо! – adelbertc

+0

Ах ах! Вы перенаправляете входные данные из файла в 'stdin'. 'stdin' - поток текстового режима и не подходит для того, что вы делаете. Во всяком случае ... у вас есть «^ @» во входном файле? – pmg

0

сделать следующие исправления:

- outfile = fopen(argv[1], "w"); 
+ outfile = fopen(argv[1], "wb"); 


- c = (unsigned char) temp; 
+ c = (unsigned char) (char) temp; 
+0

'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Как следует из pmg, 'c' должен быть' int', но я не вижу необходимости использовать «char» даже в этом случае. – ibid

+0

Это не символ после того, как он исправляет другой. Меня сожгли несколько раз, когда сузились и меняли подпись на одном и том же актере. – Joshua

+0

'getchar' возвращает, если не' EOF', 'unsigned char' придает' int'. Обратное должно работать. – ibid

1

Есть несколько вещей, которые необходимо исправить: 1) Повторно открыть STDIN как двоичный файл. freopen(NULL, "rb", stdin); 2) Откройте файл outfile как: fopen (argv [1], "wb"); 3) temp должно быть типа int.

+0

В соответствии с [Стандартом C99] (http://port70.net/~nsz/c/c99/n1256.html#7.19.5.4) «Определено, какие изменения режима разрешены (если они есть) , и при каких обстоятельствах ". – pmg

+0

Учитывая его состояние, не требующее, чтобы он находился в UNIX. – Joshua

Смежные вопросы