2013-07-30 3 views
0
/*Write a program that indefinitely takes in files to append to a master 
    file. If the file names are the same, don't do it. If there's an error, 
    don't do it. Exit with a blank line. Use a custom buffer.*/ 

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define MAX_NAME 25 
#define BUFSIZE 1024 
int append(FILE *, FILE *); 

int main(){ 
    char src[MAX_NAME], mainfile[MAX_NAME]; 
    FILE *src_ptr, *mainfile_ptr; 
    int successes = 0; 

    puts("Enter name of main file"); 
    if(gets(mainfile) == NULL){ 
     fprintf(stderr, "Error, couldn't get filename\n"); 
     return 1; 
    } 
    if((mainfile_ptr = fopen(mainfile, "ab")) == NULL){ 
     fprintf(stderr, "Error, couldn't open mainfile\n"); 
     return 1; 
    } 

    do{ 
     puts("Enter a filename to be appended"); 
     if(gets(src) == NULL || src[0] == '\0' || strcmp(src, mainfile) == 0){ 
      if(src[0]) 
       puts("Error, couldn't get filename!"); 
      continue; 
     } 

     if((src_ptr =fopen(src, "rb")) == NULL){ 
      puts("Error, could not open file"); 
      continue; 
     } 

     if(setvbuf(src_ptr, NULL, _IOFBF, BUFSIZE) != 0){ 
      puts("Couldn't create filebuffer!"); 
      continue; 
     } 

     if(append(src_ptr, mainfile_ptr) != 0){ 
      fflush(src_ptr); 
      puts("Couldn't append!"); 
      continue; 
     } 

     fclose(src_ptr); 
     ++successes; 
     printf("Successfully appended %s, %d files total\n", src, successes); 

    }while(src[0] != '\0'); 

    fclose(mainfile_ptr); 
    printf("Successfully appended %d files, bye!\n", successes); 
    return 0; 
} 


int append(FILE *src, FILE *mainfile){ 
    size_t bytes = 0; 
    static char buffer[BUFSIZE]; 
    while(bytes = (fread(buffer, sizeof(char), BUFSIZE, src)) > 0) 
     fwrite(buffer, sizeof(char), BUFSIZE, mainfile); 

    if(ferror(src) || ferror(mainfile)) 
     return 1; 

    return 0; 
} 

Привет, там. На примере C Primer Plus я написал программу, которая добавила бы содержимое файлов, указанных пользователем в главный файл. Первоначально я написал, что намеревался использовать его только с текстовыми файлами , но затем я сменил его на работу в двоичном режиме. Я использовал его для добавления четырех файлов. Я получил некоторые странные результаты, и я не знаю, почему. Вот скриншот готового файла (мне нужно было сделать снимок экрана, потому что он полон действительно странных символов). Я получаю тот же результат , не открывая их в двоичном режиме с помощью fopen. Кажется, что «добавляет» мои файлы несколько раз, некоторые из которых только наполовину, а затем и другая половина.Как правильно использовать fread() и fwrite() в моей программе?

Где я ошибся?

File being viewed in gvim

Я не знаю, почему это изменить размер его так много.

+1

'gets' будет отменен. – BLUEPIXY

+0

Возможно, слишком мета, но 'strcmp' не является хорошим способом проверить, совпадает ли ваш входной файл с вашим выходным файлом. Упражнение: Можете ли вы назвать одну или несколько причин? – usr2564301

+0

Обратите внимание, что вы никогда не должны использовать функцию 'gets()', которая по своей сути является небезопасной. Эта функция была устарела на C99 и полностью исключена из C11. –

ответ

9
while(bytes = (fread(buffer, sizeof(char), BUFSIZE, src)) > 0) 
    fwrite(buffer, sizeof(char), BUFSIZE, mainfile); 

должен быть

while((bytes = fread(buffer, sizeof(char), BUFSIZE, src)) > 0) 
    fwrite(buffer, sizeof(char), bytes, mainfile); 

В тех случаях, когда fread возвращает меньше, чем BUFSIZE байт, вы пишете данные из предыдущего чтения в mainfile.

Вы также можете проверить, что fwrite возвращает bytes, выбирая, следует ли прервать или повторить запись оставшейся части буфера, если меньше написано.

+1

Я думаю, что вы имеете в виду: 'while ((bytes = fread (buffer, sizeof (char), BUFSIZE, src))> 0)', left '(' before 'bytes =' **? ** –

+1

О, черт возьми, вы Верно. Когда буфер не полностью заполнен, я все еще записываю байты BUFSIZE вместо фактического количества, которое было прочитано. –

+1

@GrijeshChauhan Спасибо, я пропустил это. Теперь добавил к моему ответу. – simonc

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