Почему fgets считывает мусор после строки?

#c #string #io #fgets

Вопрос:

Имея этот код:

 #include lt;stdio.hgt; #include lt;stdlib.hgt;  #define BUFLEN 255  char *unspace(char *s) {  int count = 0;  for (int i = 0; s[i] != ''; i  )  {  if (s[i] != ' ' amp;amp; s[i] != 't' amp;amp; s[i] != 'n')  {  s[count  ] = s[i];  }  else  {  s[count  ] = ' ';  while (s[i] == ' ' || s[i] == 't' || s[i] == 'n')  {  i  ;  }  i--;  }  }  s[count] = '';  return s; }  char *translate(char *s) {  int count = 0;  for (int i = 0; s[i] != ''; i  )  {  if (  (s[i] gt;= 'a' amp;amp; s[i] lt;= 'z') ||  (s[i] gt;= 'A' amp;amp; s[i] lt;= 'Z') ||  (s[i] gt;= '0' amp;amp; s[i] lt;= '9') ||  s[i] == '.' ||  s[i] == ',' ||  s[i] == '!' ||  s[i] == '?' ||  s[i] == ' ')  {  s[count  ] = s[i];  }  else  {  while (  (s[i] lt; 'a' || s[i] gt; 'z') amp;amp;  (s[i] lt; 'A' || s[i] gt; 'Z') amp;amp;  (s[i] lt; '0' || s[i] gt; '9') amp;amp;  s[i] != '.' amp;amp;  s[i] != ',' amp;amp;  s[i] != '!' amp;amp;  s[i] != '?' amp;amp;  s[i] != ' ')  {  i  ;  }  i--;  }  }  s[count] = '';  return s; }  char *toUpper(char *str) {  for (int i = 0; str[i] != ''; i  )  {  if (str[i] gt;= 'a' amp;amp; str[i] lt;= 'z')  {  str[i] -= 32;  }  }  return str; }  int main() {  // ON STRINGS WORKS CORRECTLY  // char s1[] = "Ahoj, @$~ja^amp;k se malt;gt;s?";  // char s2[] = "{Ma}m se $#$## dobre! dnes je *amp;amp;33// stupnu.";   // puts(unspace(toUpper(translate(s1))));  // -gt; AHOJ, JAK SE MAS?  // puts(unspace(toUpper(translate(s2))));  // -gt; MAM SE DOBRE! DNES JE 33 STUPNU.   FILE *fp = fopen("data.txt", "r");  char buf[BUFLEN] = {0};   while (fgets(buf, BUFLEN, fp))  {  puts(unspace(toUpper(translate(buf))));  } }  

и этот файл данных:

 $ cat data.txt Ahoj, @$~ja^amp;k se malt;gt;s?  {Ma}m se $#$## dobre! dnes je *amp;amp;33// stupnu.  

Я всегда получаю результат с мусором в конце:

 $ ./a.out AHOJ, JAK SE MAS? 2Y9CNP5V MAM SE DOBRE! DNES JE 33 STUPNU.2Y9CNP5V  $ ./a.out AHOJ, JAK SE MAS? Y.XHNPVU MAM SE DOBRE! DNES JE 33 STUPNU.Y.XHNPVU  $ ./a.out AHOJ, JAK SE MAS? 9WAGPAV MAM SE DOBRE! DNES JE 33 STUPNU.9WAGPAV  $ ./a.out AHOJ, JAK SE MAS? MP9SU MAM SE DOBRE! DNES JE 33 STUPNU. MP9SU  

Программа правильно считывает строку из файла, но добавляет несколько случайных символов в конце. Почему это так? И как избавиться от этих персонажей?

Комментарии:

1. Потому что, когда вы сталкиваетесь с символом новой строки, вы вводите цикл while, в котором вы больше не проверяете .

2. @Cheatah я этого не понимаю. Новая строка отвечает за fgets

3. @milanHrabos Newline несет ответственность за fgets , что это значит?

4. Я неправильно истолковал код, но, как ни странно, проблема все та же. В while цикле translate вы не проверяете .

Ответ №1:

В функции translate добавьте условие « (s[i] != '') amp;amp; » в while цикл.

Таким образом, цикл становится:

 else  {   while ((s[i] != '') amp;amp;   (s[i] lt; 'a' || s[i] gt; 'z') amp;amp;  (s[i] lt; 'A' || s[i] gt; 'Z') amp;amp;  (s[i] lt; '0' || s[i] gt; '9') amp;amp;  s[i] != '.' amp;amp;  s[i] != ',' amp;amp;  s[i] != '!' amp;amp;  s[i] != '?' amp;amp;  s[i] != ' ')  {  i  ;   }