2015-09-12 3 views
1

Im пишет мою собственную упрощенную версию классической программы UNIX «wc» (количество слов). Он подсчитывает количество строк, слов и символов. Все эти функции работают нормально. Но где я сталкиваюсь с трудностями, когда я пытаюсь прочитать несколько файлов из * argv [x]. Мне нужно сделать каждую переменную в массиве и запустить весь процесс с помощью циклов, чтобы добиться того, что им нужно.C - чтение нескольких файловых потоков

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

Любая помощь очень ценится :)

/* 
*  [PROGRAM] wc (word count) 
*  [AUTHOR] Jesper M. Olsen @ jm0.codes 
*   [DATE] September 9th 2015 
*  [PURPOSE] Returns number of lines, words, and characters in a file 
* 
* [DESCRIPTION] This program is meant to be utilized as a handy little browsing tool. 
*     For instance, while moving through the filesystem of a programming archive, 
*     just type 'wc <filename>' and you will get number of lines, words and characters returned promptly. 
*/ 

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

int main(int argc, char *argv[]) 
{ 
    if (argc == 1) 
     return -1; 

    int numL[argc]; /* initialize array value placeholders */ 
    int numW[argc]; 
    int numC[argc]; 
    int getC[argc]; 
    int getW[argc]; 

    int setNull; 
    for (setNull = 1; setNull <= argc-1; setNull++) { /* assign ZERO to value placeholders */ 
     numL[setNull] = 0; 
     numW[setNull] = 0; 
     numC[setNull] = 0; 
     getW[setNull] = 0; 
    } 

    int x; 
    FILE *fOp[argc-1]; 
    for (x = 1; x <= argc-1; x++) { /* open file stream for each file */ 
     fOp[x] = fopen(argv[x], "r"); 
     if (fOp[x] == NULL) 
      return -1; 
    } 

     int y; 
     for (y = 1; (getC[y] = getc(fOp[y])) != EOF; y++) { 
      if (getC[y] == '\n') numL[y]++; 
      if (getC[y] == ' ' || getC[y] == '\n' || getC[y] == '\t') getW[y] = 0; 
      else if (getW[y] == 0) { 
       getW[y] = 1; 
       numW[y]++; 
      } numC[y]++; 
     } 

     int z; 
     for (z = 1; z <= argc-1; z++) { /* close files */ 
      fclose(fOp[z]); 
     } 

    int c; 
    for (c = 1; c <= argc-1; c++) { 
     printf("[%s] %dL %dW %dC\n", argv[c], numL[c], numW[c], numC[c]); 
    } 

    return 0; 

} 
+0

Примечание. Вы никогда не используете в своем коде индекс '0' любого массива. – ameyCU

+0

Пожалуйста, подключите вывод отладчика backtrace, чтобы мы знали, в какой строке находится segfault. –

+0

'FILE * fOp [argc-1];' должен быть 'FILE * fOp [argc];' и я также предпочитаю видеть '

ответ

0

Я думаю, что проблема может быть здесь -

for (y = 1; (getC[y] = getc(fOp[y])) != EOF; y++) { 
     if (getC[y] == '\n') numL[y]++; 
     if (getC[y] == ' ' || getC[y] == '\n' || getC[y] == '\t') getW[y] = 0; 
     else if (getW[y] == 0) { 
      getW[y] = 1; 
      numW[y]++; 
     } numC[y]++; 
    } 

Как массивы могут argc число элементов, но с этого цикла вы можете читать и хранить целые числа более argc в getC. Таким образом, получение Seg Fault.

Но мы не знаем, что внутри файлов мы не можем быть уверены.

Попробуйте увеличить размер массивов.

Примечание. Лучше инициализировать массив, начиная с индекса 0. В этом коде вы не используете индекс 0.

+0

Я обнаружил ошибку seg после выполнения некоторых тестов и, конечно же, достаточно. Он был помещен в цикл for, который вы описываете ^^. Это логическая ошибка, конечно, вызвала ошибку. Я просто помещаю время в цикл for, поэтому он будет оценивать каждый файл по назначению. Вот рабочий код: http://codepad.org/6KbtiriR –

+0

@JesperOlsen Я не знал, что было в файле, поэтому было недостаточно.Но убедитесь, что ваш код работает нормально. Приветствия! – ameyCU

+0

@JesperOlsen. Сначала я был удивлен, но теперь внимательно наблюдал, что 'y' не был ограничен в предыдущем' for loop', который был необходим, поскольку он мог бы получить индекс из связанной причины ошибки. – ameyCU

1

Это приведет к Segfault, когда вы достигнете последнего файла

FILE *fOp[argc-1]; 

for (x = 1; x <= argc-1; x++) { /* open file stream for each file */ 
    fOp[x] = fopen(argv[x], "r"); 
    if (fOp[x] == NULL) 
     return -1; 
} 

, потому что массив не является достаточно большим. Он должен быть

FILE *fOp[argc]; 

Ошибкой было бы легче увидеть, если вы использовали

< argc 

вместо

<= argc-1 

в ваших петель.

+0

@ameyCU, нет, он индексирует массив с элементами 'argc-1'' argc-1'. –

+0

Я предполагаю, что он не использует индекс '0', потому что его не интересует' argv [0] ' –

+0

Что с этим делать? Он не использует его. –

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