2017-01-11 17 views
1

Ниже решено. Я смущен, чтобы сказать, что мой исходный файл находился в другой папке, чем мой .c файл, и я не потрудился проверить, вернул ли fopen() null. Большое спасибо этому удивительному сообществу и извинения за то, что вы занимаете свое время с такой глупой проблемой.Определение конца строки

Я пытаюсь читать слова разных размеров из файла, где слова разделены строками (например, слово на каждой строке). По какой-то причине ниже компилируется, но возвращает ошибку сегментации при запуске программы.

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

int main(void) { 
    FILE *dictionary = fopen("small.txt", "r"); 

    char word[46]; 
    int index = 0; 

    for (int c = fgetc(dictionary); c != '\n'; c = fgetc(dictionary)) { 
     word[index] = c; 
     index++; 
    } 

    index = 0; 

    fclose(dictionary); 

    return 0; 
} 

Совет очень ценит.

+0

Это поможет, если мы сможем увидеть ваш файл. – RoadRunner

+0

Его два слова на двух строках. в конечном итоге это будет полный словарь ... – Tikhon

+0

Не добавляйте нулевой байт в конец вашего массива. – RoadRunner

ответ

1

Судя по вашему коду, похоже, что вы не добавляете символ \0 в конце вашего массива. Не делать этого опасно и приведет к неопределенному поведению. Этот нуль-байтовый символ обозначает конец строки в C.

Вы также не проверяете возвращаемое значение с FILE *dictionary. Это может вернуть NULL, если ваша программа не сможет открыть файл.

Проверка на EOF от getc() также неплохая идея.

Вы могли бы хотеть что-то вроде этого:

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

#define WORDSIZE 46 

int main(void) { 
    FILE *dictionary; 
    char word[WORDSIZE+1]; /* +1 for null-byte */ 
    int index = 0, ch; 

    /* opening file with error checking */ 
    dictionary = fopen("small.txt", "r"); 
    if (!dictionary) { 
     fprintf(stderr, "Cannot open file.\n"); 
     return 1; 
    } 

    while ((ch = getc(dictionary)) != EOF && ch != '\n') { 
     if (index < WORDSIZE-1) { 
      word[index++] = ch; 
     } 
    } 

    /* terminating string */ 
    word[index] = '\0'; 

    printf("Word found: %s\n", word); 

    fclose(dictionary); 

    return 0; 
} 
+0

Код пропустил проверку 'getc()' для успеха. – alk

+0

Спасибо, ваши очки хорошо приняты, и я лучше, чем делать обе ошибки, которые вы указали. Я выяснил свою проблему ... Я смущен, чтобы сказать Файл small.txt был в другой папке из файла test.c – Tikhon

3

Ваша программа может потерпеть неудачу по нескольким причинам:

  • Вы не проверяют на неудачу, чтобы открыть файл. fgetc() вызывает неопределенное поведение, если поток FILE* составляет NULL.
  • Слова могут быть длиннее 45 символов, тогда вы вызываете неопределенное поведение, сохраняя символы за пределами массива.
  • Вы не проверяете окончание файла: если вы сталкиваетесь с окончанием файла до конца строки, как и в случае с пустым файлом, fgetc() возвращает EOF и вы повторно храните это значение в массиве, вызывая неопределенные по той же причине, что и выше.
  • Обратите внимание, что вы только читать одно слово ...

Вот более простой вариант, который больше не должны аварий:

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

int main(void) { 
    FILE *dictionary = fopen("small.txt", "r"); 
    char word[46]; 
    size_t index = 0; 
    int c; 

    if (dictionary == NULL) { 
     fprintf(stderr, "cannot open dictionary file 'small.txt': %s\n" 
       strerror(errno)); 
     return 1; 
    } 
    while ((c = getc(dictionary)) != EOF && c != '\n') { 
     if (index < sizeof(word) - 1) { 
      word[index++] = c; 
     } 
    } 
    word[index] = '\0'; 

    fclose(dictionary); 

    return 0; 
} 
+0

Вызов 'perror' в случае' if (dictionnary == NULL) ' по крайней мере, будет записывать/распечатывать полезную диагностическую информацию. – alk

+1

@alk: ответ обновляется с помощью 'strerror()'. – chqrlie

1

сложения ответов, чтобы обеспечить полные ошибку при проверке цикла считывания должно следовать следующее:

if (EOF == c) 
    { 
    if ferror(dictionary) 
    { 
     fprintf(stderr, "fgetc() failed."); /* fgetc doe not set errno. */ 
    } 
    }