fgets 和 gets 的区别

Difference between fgets and gets

fgets()gets()有什么区别?

我正在尝试在用户只点击 "enter" 时打破我的循环。它与 gets() 配合使用效果很好,但我不想使用 gets()。 我尝试了 fgets()scanf(),但我没有得到与 gets() 相同的结果。 fgets() 打破循环,无论用户输入什么文本!这是我的代码:

void enter(void)
{
  int i,

  for(i=top; i<MAX; i++)
    {
      printf(".> Enter name (ENTER to quit): ");
      gets(cat[i].name);

      if(!*cat[i].name)
         break;

      printf(".> Enter Last Name: ");
      scanf("%s",cat[i].lastname);
      printf(".> Enter Phone Number: ");
      scanf("%s",cat[i].phonenum);
      printf(".> Enter e-Mail: ");
      scanf("%s",cat[i].info.mail);
      printf(".> Enter Address: ");
      scanf("%s",cat[i].info.address);
      printf("\n");
    }
  top = i;
}

gets 和 fgets 之间存在问题的区别在于,gets 会从输入行中删除尾随的“\n”,但 fgets 会保留它。

这意味着 fgets 返回的 'empty' 行实际上是字符串“\n”。

令人讨厌的区别,这意味着最好完全避免 gets,如果你给 gets 的一行太长,你的程序将以非常糟糕的方式崩溃。

gets()fgets() 之间的区别是 fgets() 将换行符留在缓冲区中。因此,与其检查输入的第一个元素是否为 0,不如检查它是否为 '\n';

fgets(cat[i].name, sizeof cat[i].name, stdin);
if (cat[i].name[0] == '\n' || cat[i].name[0] == 0) {
    // empty line or no input at all
    break;
} else {
    // remove the trailing newline
    int len = strlen(cat[i].name);
    cat[i].name[len-1] = 0;
}

您可以将 fgets() 与 STDIN 一起使用。 这个函数是安全的,总是在字符串末尾插入一个'\0'。

一个例子:

char inputbuffer[10];
char *p;
p = fgets(inputbuffer, sizeof(inputbuffer), stdin);
printf(">%s<\n", p);    /* p is NULL on error, but printf is fair */

在此示例中,您最多可以得到 9 个字符 + '\0'。

删除gets()scanf().
创建一个辅助函数来处理 和限定 用户输入。

// Helper function that strips off _potential_ \n
char *read1line(const char * prompt, char *dest, sizeof size) {
  fputs(prompt, stdout);
  char buf[100];
  *dest = '[=10=]';
  if (fgets(buf, sizeof buf, stdin) == NULL) {
    return NULL;  // EOF or I/O error
  }
  // Remove potential \n
  size_t len = strlen(buf);
  if (len > 0 && buf[len-1] == '\n') {
    buf[--len] = `[=10=]`;
  }
  // Line is empty or too long
  if (len == 0 || len >= size) return NULL;
  return memcpy(dest, buf, len+1);
}

void enter(void)
{
  int i;

  for(i=top; i<MAX; i++)
    {
      if (read1line(".> Enter name (ENTER to quit): ", 
          cat[i].name, sizeof cat[i].name) == NULL) break;
      if (read1line(".> Enter Last Name: ", 
          cat[i].lastname, sizeof cat[i].lastname) == NULL) break;
      if (read1line(".> Enter Phone Number: ", 
          cat[i].phonenum, sizeof cat[i].phonenum) == NULL) break;
      if (read1line(".> Enter e-Mail: ", 
          cat[i].info.mail, sizeof cat[i].info.mail) == NULL) break;
      if (read1line(".> Enter Address: ", 
          cat[i].info.address, sizeof cat[i].info.address) == NULL) break;
    }
  top = i;
}

fgets()gets()的一些属性:

fgets() 读取输入并保存到缓冲区,直到:
1) 缓冲区差 1 满 - 或 -
2)遇到'\n'-或-
3) 流达到文件结束条件 - 或 -
4) 发生输入错误。

gets() 执行上面的 #2 - #4 除了 它扫描,但不保存 '\n'.
gets() 在 C99 中贬值,不再是 C11 的一部分。