Реализация 'кошка' в c - wwwmc?(Что не так с моим кодом) - PullRequest
0 голосов
/ 01 ноября 2011

Мой код работает нормально. У меня есть две проблемы с этим, хотя. Во-первых, в конце печати файлов на стандартный вывод, это вызывает ошибку сегментации.

Во-вторых, я не могу использовать fputs для распечатки данных, потому что у меня сразу возникает ошибка сегментации. Поэтому, чтобы исправить это, я использую put, который печатает его нормально, но добавляет 'n' после каждой строки, делая текст одинарным интервалом, а также ошибку сегмента в конце.

#include <stdio.h>
#include <string.h>

void concat(char *arg){

    char string[256];
    FILE *fp = fopen(arg, "r");

    while(!feof(fp)){
        fgets(string, 256, fp);
        //fputs(string, fp);
        puts(string);
    }

    fclose(fp);

}

void stdincat(){

    char string[256];   
    while(!feof(stdin)){
        fgets(string, 256, stdin);
        fputs(string, stdout);
    }
}

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

    char argvalues[256][40];

    if(argv[1] == NULL)
        stdincat();
    else if(argv[1] != NULL){
        int i;

        for(i=1;i<=(argc);i++){
            concat(argv[i]);
        }
    }

    return 0;
}

Ответы [ 2 ]

1 голос
/ 01 ноября 2011

Звонок на fputs, который вы прокомментировали в concat, пытается записать в fp, который вы открыли только для чтения, поэтому неудивительно, что он не будет / не работает.

Кроме этого, ваши циклы чтения: while(!feof(fp)) { (и аналогичные, кроме stdin вместо fp) следуют знакомому, широко распространенному анти-паттерну - подобные циклы не / не будут / могут не работает правильно. Обычно вы хотите прочитать и проверить на успех в той же операции:

while(fgets(string, 256, stdin))
    fputs(string, stdout);

Редактировать: Я должен также упомянуть, что я бы предпочел избежать дублирования кода в concat и stdincat. Я предпочел бы передать FILE * для чтения в качестве параметра, чтобы вы использовали тот же код для чтения из stdin или из других произвольных файлов:

// Warning: untested code.
// error checking omitted for readability.
void catfile(FILE *file) { 
    char line[256];
    while (fgets(line, sizeof(line), file))
        puts(line);
}

int main(int argc, char **argv) { 
    int i;
    if (argc == 1)
        catfile(stdin);
    else for (int i=1; i<argc; i++) {
        FILE *infile = fopen(argv[i], "r");
        catfile(infile);
        fclose(infile);
    }
    return 0;
}

Наконец, я хотел бы отметить, что если вы собираетесь скопировать весь файл, fgets, вероятно, является , а не наиболее эффективным способом выполнения этой работы. fread может быть более подходящим. Пока вы работаете над этим, вы также можете использовать чтение и запись в двоичном режиме.

0 голосов
/ 01 ноября 2011

Вы не можете писать в поток, который вы открыли только для чтения, вы должны использовать stdout для fputs в функции concat

...