【问题标题】:fgets limiting input lengthfgets 限制输入长度
【发布时间】:2015-02-18 13:11:03
【问题描述】:

当我输入姓氏之类的数据时,我得到了它,因此它限制为 10 个字符,但是当我尝试输入姓氏时,从名字中排除的字符被放入姓氏中.例如,如果我输入aaaaaaaaaab,它将保留a,但b 将被放入姓氏中。

有什么建议可以解决这个问题吗?我希望它将长度限制在正确的数量。

printf("you chose add new record\n"); 
printf("enter the person information: \n");
printf("Please enter the first name: \n");
//limits to size 10
char namein[11];
fgets(namein, 11, stdin);
printf("the first name was: %s\n", namein);

printf("Please enter the last name: \n");
//limits to size 20
char lastin[21];
fgets(lastin, 21, stdin);
printf("the last name was: %s\n", lastin);

【问题讨论】:

  • 您是要坚持在两行输入中输入名字和姓氏,还是在单行中接受“firstname lastname”为有效?使用的技术是不同的。前者更容易;您可以预先阅读整行内容(使用 更大的缓冲区)并使用 sscanf() 对缓冲区进行后处理。请注意,如果有人输入Jim E Cork,您的fgets() 将把Jim E Cork 变成namein;目前尚不清楚这就是你想要的。此外,下一个 fgets() 将在 'Jim E Cork' 之后获得换行符,这也不是您想要的。
  • 我基本上只是寻找输入的前 10 个字符,所以如果名称是 jimmyeguysZ,Z 将被剥离并仅将输入保存为 jimmyeguys

标签: c


【解决方案1】:

检查使用fgets()的结果。

如果缓冲区包含\n,则无需查找更多。否则在'\n'EOF 之前消耗潜在的额外数据。

int ConsumeExtra(const char *buf) {
  int found = 0;
  if (strchr(buf, '\n') == NULL) {
    int ch;
    // dispose of extra data
    while ((ch = fgetc(stdin)) != '\n' && ch != EOF) {
      found = 1;
    }
  }
  return found;
}

char namein[11];
if (fgets(namein, sizeof namein, stdin) == NULL) Handle_EOForIOError();
if (ConsumeExtra(namein)) Handle_ExtraFound(); 

注意:建议输入缓冲区不要太小。最好读入一个通用的大缓冲区,然后在保存到namein 之前限定输入。 IOW,更喜欢将输入和扫描/解析分开。

char buffer[100]
char namein[11];
if (fgets(namein, sizeof buf, stdin) == NULL) Handle_EOForIOError();
if (ConsumeExtra(buf)) Handle_InsaneLongInput();

int n = 0;
sscanf(buffer, "%10s %n", namein, &n);
if (n == 0 || buf[n]) Handle_NothingOrExtraFound();

【讨论】:

  • 好的,谢谢,但究竟是什么原因导致多余的字母从第一个输入中剥离并添加到第二个输入中?
  • @Austin Smith ConsumeExtra() 消耗额外的char 并将它们扔到bit bucket 中。因此,当下一个 fgets() 出现时,它会检索新的用户输入。
【解决方案2】:

在进行下一次读取之前,您必须读取整个输入缓冲区。这种操作称为“排空”输入。

所以你的代码应该是这样的

get the first name
read the first name
drain the input
print the prompt for the last name
read the last name

耗尽输入看起来大致像

while (there is data that can be read) {
  read a character
}

【讨论】:

  • 我觉得你的“排水”有点太热情了;它通常应该是“while(下一个字符不是 EOF 或换行符)”,如果您要坚持每行输入一个单词。
  • @JonathanLeffler 也许,但在呈现下一个查询之前真的有任何东西可以保留吗?我的意思是,如果他们敲了五次回车,你真的希望下一个拉取的输入是空的吗?
  • 我想这取决于您所说的while (there is data that can be read) 是什么意思。没有标准函数可以查看输入缓冲区中是否已有更多字符。读到换行符(或 EOF,如果最后一行没有换行符)是一个合理的解释,但您可能有一些更复杂的方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-21
  • 2013-12-04
  • 1970-01-01
  • 2012-02-29
  • 2015-04-02
  • 1970-01-01
相关资源
最近更新 更多