#c #terminal #fopen
Вопрос:
Я создаю небольшую программу на языке Си для подсчета количества строк файла, но каждый раз, когда я компилирую и запускаю ее в своем терминале, программа зависает (не показывает никаких ошибок, но программа не может прочитать следующие записи).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void find_word (void);
int main (int argc, char *argv[])
{
find_word();
return 0;
}
void find_word (void)
{
FILE *file;
int character;
int line_number;
file = NULL;
character = 0;
line_number = 0;
file = fopen ("word_source.txt", "r");
if (file == NULL)
{
printf("Errorn");
exit (0);
}
printf("%c", character);
character = fgetc(file);
while (character != EOF)
{
if (character == 'n')
{
line_number ;
}
}
fclose(file);
printf("%d", line_number);
}
Я понятия не имею, в чем проблема, поэтому я создал еще один файл, и этот работает:
#include <string.h>
#include <stdio.h>
int main (int argc, char *argv[])
{
FILE *file = fopen ("word_source.txt", "r");
if (file == NULL)
printf("No");
else
printf("Yes");
return 0;
}
Комментарии:
1. символ @user3121023 уже является fgetc(файл)
2. @zelph14 ваш код считывает ровно один символ из файла. Вы хотите прочитать все символы файла.
3. «Ошибка» не является полезным сообщением об ошибке, вы записываете его в неправильный поток, и это кажется странным
exit(0)
и утверждает об успехе при этой ошибке. Попробуй:const char *path = "word_source.txt"; if( (file = fopen(path, "r")) == NULL) { perror(path); exit(EXIT_FAILURE);}
4. @user3121023 о да, это было так просто… спасибо !!
Ответ №1:
fopen
здесь не бесплатно. Ваш код, похоже, замерзает, потому что у вас здесь бесконечный цикл:
character = fgetc(file); // read one char from file
while (character != EOF) // this loop is repeated indefinitely
{ // because character never changes inside the loop
if (character == 'n')
{
line_number ;
}
}
Ты хочешь этого:
while (1)
{
character = fgetc(file); // reads a character from the filee
if (character == EOF) // if end of file
break; // stop the loop
if (character == 'n') // is character read a newline?
{
line_number ; // increment line number
}
}
или более компактным:
while ((character = fgetc(file)) != EOF)
{
if (character == 'n') // is character read a newline?
line_number ; // increment line number
}
Комментарии:
1. @JonathanLeffler добавил более короткую версию. Я полагаю, что это более идиоматично, но, возможно, труднее понять новичку.
2. @JonathanLeffler Первая версия была понятной и понятной. «Идиоматический» C с назначением, втиснутым в
while
инструкцию, является конструкцией, настолько подверженной ошибкам, что отраслевые стандарты кодирования, такие как MISRA, касающиеся надежности кода и безопасности человека, запрещают его использование в совместимом коде. MISRA C:2004, 13.1, MISRA C :2008, 6-2-1, MISRA C:2012, 13.4 и сертификат, EXP45-C применяются все и, вероятно, немало других. Видишь wiki.sei.cmu.edu/confluence/display/c/… только для одного примера.3. Подсказка: если ваша программа «останавливается», проверьте использование процессора. Если 0, он заблокирован, если 100%, он зацикливается.