2012-05-17 2 views
1

У меня есть программа, которая считывает имена студентов и классов построчно из текстового файла с помощью fgets и буфер объявлен как:Сравнение строк в C

char buffer[1024]; 

Теперь файл должен заканчиваться строкой «конец «на линии все само по себе.

Как указать цикл while для завершения, когда buffer == "end"?

Я пробовал использовать strcmp, но это почему-то.

+2

'strcmp' является правильной функции использовать, это должно быть что-то еще. – dasblinkenlight

+0

Это домашнее задание? Можем ли мы увидеть ваш код? – Eric

+2

Вы должны выяснить, почему 'strcmp' segfaults вместо того, чтобы избежать проблемы. –

ответ

4

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

#include <string.h> 

if(!strcmp(line, "end\n") || !strcmp(line, "end\r\n")) 
    break; 

или аналогичные должны сделать трюк. Обратите внимание на ! перед strcmp, поскольку strcmp возвращает 0 (т. Е. False), если строки совпадают. Но я думаю, вы уже знаете, что, поскольку вы уже упомянули strcmp в своем вопросе.

О проблеме segfault: Вы уверены, что ни один из указателей, переданных в strcmp, не имеет значения NULL? Большинство стандартных библиотек C не делают никакой проверки ошибок здесь и будут работать в segfaults при попытке прочитать память на *(0).

Еще одна возможная проблема, которая возникает у меня в голове, заключается в том, что использование strcmp, конечно, будет работать только в том случае, если вы уже разделили свой буфер на массив одиночных строк. strtok_r, вероятно, наиболее подходит для этой задачи (Altough quite tricky).

+1

Второй тест с '\ r' не нужен; если вы читаете в текстовом режиме, то окончание строк, привязанных к ОС, переводится в '' \ n''. –

+0

@ KeithThompson: Я не думаю, что это безопасно предположить. В любой системе POSIX есть только один способ открыть файл с использованием стандартной библиотеки C ('fopen'), и в нем, в стандарте, указано, что' r' и 'rb' являются идентичными режимами. – dreamlax

+0

Да, потому что текстовые файлы POSIX используют * только * '' \ n'' для завершения строк. В Windows, например, '' r "' и '" rb "' различны; '' r "' переводит '\ r \ n' в' \ n', а '' rb "' не делает. Все становится сложным, когда вы читаете файлы в формате внешнего текста, но я не думаю, что OP должен беспокоиться об этом. –

0

Почему бы просто не использовать форматированный ввод-вывод, если формат текста в файле исправлен и используется! EOF для циклирования?

Например:

while(fp!=EOF) 
{ fscanf(fp,"%s %s %d",name,grades, &marks); 
    printf("Name: %s\tGrade: %s\t Marks: %d\n",name,grade,marks); 
} 

Это автоматически обнаруживает конец файла, который будет также удалить условие наличия строки «конец» в текстовом файле.

+0

Это ужасно, почему это стоит? Кто вам сказал, что 'fp! = EOF' верен? Также прочитайте руководство или документацию для 'fscanf()'. –

0

Использование strncmp(buffer, "end", 3) для сравнения первых трех символов вместе с if(3 == strlen(buffer), чтобы убедиться, что конец не запускает линию, должен решить проблему.

+0

Если это помогает, это потому, что он забывает о '' \ n''. Лучше иметь дело с '' \ n'' напрямую. Использование 'strncmp (line," end ", 3") 'также создает ложные положительные результаты для строк * начиная * с \" end "\. –

+0

@KeithThompson Я запутался в исходном сообщении, а потому, должен появляться на линии сам по себе. – octopusgrabbus

+0

@octopusgrabbus: Дело в том, что 'strncmp (buffer,« end », 3)' будет неправильно указывать совпадение на строке, состоящей из «выносливости». –

0

char * fgets (char * ограничение s, int n, FILE * ограничивающий поток);

Функция fgets() должна считывать байты из потока в массив, на который указывает s, до тех пор, пока не будут прочитаны n-1 байты или не будет прочитано и не передано s, или не будет обнаружено условие конца файла. Затем строка заканчивается нулевым байтом.

поэтому, когда вы читаете строку «end», элемент в буфере должен быть {'e', 'n', 'd', '\ n', '\ 0'}, вы можете использовать strcmp следующим образом :

size_t len = strlen(buffer); 
if (buffer[len - 1] == '\n') 
{ 
    buffer[len - 1] == '\0'; 
} 

if (strcmp(buffer, "end") == 0) 
{ 
    //end 
} 

или

if (strncmp(buffer, "end", 3) == 0) 
{ 
    //end 
}