fgets和gets之间的区别

时间:2015-02-08 22:18:27

标签: c scanf fgets gets

fgets()gets()之间的区别是什么?

当用户点击“输入”时,我正试图打破我的循环。它与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;
}

4 个答案:

答案 0 :(得分:4)

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;
}

答案 1 :(得分:2)

删除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 = '\0';
  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] = `\0`;
  }
  // 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()会在#em>上面#2 - #4除了扫描,但不保存'\n'
gets()在C99中折旧,不再是C11的一部分。

答案 2 :(得分:0)

获取和fgets之间存在问题的区别在于,删除后跟&#39; \ n&#39;从输入行,但fgets保持它。

这意味着“空”&#39; fgets返回的行实际上是字符串&#34; \ n&#34;。

令人讨厌的差异,这意味着最好避免完全避免,如果你给了一条很长的线,那么你的程序会以非常糟糕的方式崩溃。

答案 3 :(得分: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'。