【问题标题】:Why does fgets reads garbage after line?为什么 fgets 在行后读取垃圾?
【发布时间】:2021-12-15 02:32:03
【问题描述】:

拥有此代码:

#include <stdio.h>
#include <stdlib.h>

#define BUFLEN 255

char *unspace(char *s)
{
  int count = 0;
  for (int i = 0; s[i] != '\0'; i++)
  {
    if (s[i] != ' ' && s[i] != '\t' && s[i] != '\n')
    {
      s[count++] = s[i];
    }
    else
    {
      s[count++] = ' ';
      while (s[i] == ' ' || s[i] == '\t' || s[i] == '\n')
      {
        i++;
      }
      i--;
    }
  }
  s[count] = '\0';
  return s;
}

char *translate(char *s)
{
  int count = 0;
  for (int i = 0; s[i] != '\0'; i++)
  {
    if (
        (s[i] >= 'a' && s[i] <= 'z') ||
        (s[i] >= 'A' && s[i] <= 'Z') ||
        (s[i] >= '0' && s[i] <= '9') ||
        s[i] == '.' ||
        s[i] == ',' ||
        s[i] == '!' ||
        s[i] == '?' ||
        s[i] == ' ')
    {
      s[count++] = s[i];
    }
    else
    {
      while (
          (s[i] < 'a' || s[i] > 'z') &&
          (s[i] < 'A' || s[i] > 'Z') &&
          (s[i] < '0' || s[i] > '9') &&
          s[i] != '.' &&
          s[i] != ',' &&
          s[i] != '!' &&
          s[i] != '?' &&
          s[i] != ' ')
      {
        i++;
      }
      i--;
    }
  }
  s[count] = '\0';
  return s;
}

char *toUpper(char *str)
{
  for (int i = 0; str[i] != '\0'; i++)
  {
    if (str[i] >= 'a' && str[i] <= 'z')
    {
      str[i] -= 32;
    }
  }
  return str;
}

int main()
{
  // ON STRINGS WORKS CORRECTLY
  //   char s1[] = "Ahoj,      @$~ja^&k se ma<>s?";
  //   char s2[] = "{Ma}m       se $#$$## dobre!       dnes je     *&&33// stupnu.";

  // puts(unspace(toUpper(translate(s1))));
  // -> AHOJ, JAK SE MAS?
  // puts(unspace(toUpper(translate(s2))));
  // -> 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^&k se ma<>s?   
{Ma}m       se $#$$## dobre!       dnes je     *&&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

程序正确地从文件中读取该行,但在末尾添加了一些随机字符。为什么呢?以及如何摆脱这些字符?

【问题讨论】:

  • 因为当你遇到换行符时,你进入了一个while循环,你不再检查\0。
  • @Cheatah 我不明白。换行是 fgets 的责任
  • @milanHrabos Newline 负责 fgets 这是什么意思?
  • 我看错了代码,但有趣的是问题还是一样。在translate 的while 循环中,您不会检查\0。

标签: c string io fgets


【解决方案1】:

在翻译函数中,在while循环中添加条件“(s[i] != '\0') &amp;&amp;”。

所以循环变成:

else                                                   
{                                                      
  while ((s[i] != '\0') &&                             
      (s[i] < 'a' || s[i] > 'z') &&
      (s[i] < 'A' || s[i] > 'Z') &&
      (s[i] < '0' || s[i] > '9') &&
      s[i] != '.' &&
      s[i] != ',' &&
      s[i] != '!' &&
      s[i] != '?' &&
      s[i] != ' ')
  {
    i++;                                               
  }                                    

            

【讨论】:

    猜你喜欢
    • 2022-01-01
    • 2016-03-02
    • 1970-01-01
    • 2022-01-14
    • 2023-03-31
    • 1970-01-01
    • 2020-09-05
    • 2014-08-13
    • 1970-01-01
    相关资源
    最近更新 更多