【问题标题】:fgets maximum size readfgets 读取的最大大小
【发布时间】:2012-06-24 19:22:39
【问题描述】:

使用fgets输入字符串,我对读取的字符串长度有疑问。

例如,考虑以下程序。

char str[50];
int i;
int len;
printf("Enter name:\n");
fgets(str,11,stdin);
len = strlen(str);
printf("len :  %d\n",len);
  1. 如果我输入123456789strlen 给出 10。

  2. 如果我输入1234567890strlen 又是10 ??

我认为strlen 正在考虑换行符也用于字符串长度。我对么? (我理解fgets 使用换行符作为字符串的一部分)

(2)我输入正好 10 个字符有什么问题,这里的字符串长度应该是 11 对吗? 10 + 1(换行)= 11

【问题讨论】:

  • printf("len : %d",len); printf("str : %s",str); printf("hi");返回 0;添加一些打印有助于澄清下面给出的答案。注意“hi”的打印方式。

标签: c string fgets


【解决方案1】:

fgets 读取的字符最多比给定的长度参数少 1 个字符,并且 确实 保留换行符作为输入的一部分 - 只要换行符是第一个的一部分(长度 - 1 ) 字符。

所以在您的第一种情况下,假设123456789 后跟换行符,fgets 已读取包括换行符在内的 9 个字符,产生的字符串长度为 10;在第二种情况下,fgets 将在读取 10 个字符 1234567890 后停止,生成长度为 10 的字符串。

【讨论】:

  • 小修正:如果 #/characters >= max length,它将保留换行符。如下例所示。
  • @paulsm4 我相信从我的第一行就已经很清楚了:读取的字符最多比给定的长度参数少 1 个字符
【解决方案2】:

这是一个例子:

#include <stdio.h>
#include <string.h>

#define MAX_DIGITS 5

int
main ()
{
  char buf[80];
  char *s = NULL;
  printf ("\n>>Enter string, %d digits or less: ", MAX_DIGITS);
  s = fgets (buf, MAX_DIGITS+1, stdin);
  printf ("strlen(buf)=%d, buf=%s, strlen(s)=%d, s=%s\n",
    strlen(buf), buf, strlen(s), s);
  return 0;
}

示例输出,带有“MAX_DIGITS”和“MAX_DIGITS + 1”:

>>Enter string, 5 digits or less: 1
strlen(buf)=2, buf=1
, strlen(s)=2, s=1
.

>>Enter string, 5 digits or less: 12
strlen(buf)=3, buf=12
, strlen(s)=3, s=12
.

>>Enter string, 5 digits or less: 123
strlen(buf)=4, buf=123
, strlen(s)=4, s=123
.

>>Enter string, 5 digits or less: 1234
strlen(buf)=5, buf=1234
, strlen(s)=5, s=1234
.

>>Enter string, 5 digits or less: 12345
strlen(buf)=5, buf=12345, strlen(s)=5, s=12345.

>>Enter string, 5 digits or less: 123456
strlen(buf)=5, buf=12345, strlen(s)=5, s=12345.

你会注意到:

  1. 只要#/digits

  2. 当 #/digits >= MAX_DIGITS 时删除“\n”。

  3. 您的缓冲区必须容纳 MAX_DIGITS+1

【讨论】:

  • @kumar 存储换行符应该是 + 2 因为 fgets 已经拿走了一个用于存储空终止符值 -> '\0';也就是说,如果你通过它 6 它将最多读取 5 个东西(4 位 + CR 或 5 位)。如果你传递它 7 它将读取 5 位数字加上一个回车。
【解决方案3】:

实际上fgets 需要size 规范(在您的情况下为11)帐户以用于字符串末尾的\0。来自fgets 手册页:

fgets() 最多读入一个小于 size 的字符 来自流并将它们存储到指向的缓冲区中 s。在 EOF 或换行符后停止读取。如果换行 被读取,它被存储到缓冲区中。终止空值 字节 ('\0') 存储在缓冲区中的最后一个字符之后。

所以我们知道,当您输入 123456789\n 时,读取会在 \n 处停止。但是,当您输入 1234567890\n 时,fgets() 会处理输入,但它只需要 10 个字符,之后会忽略其他所有内容。

您的字符串的任何额外输入和您的字符串将在size-1fget() 与最后一个字符为\0 所以输出保持不变。

【讨论】:

    猜你喜欢
    • 2011-12-17
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-29
    • 2014-12-09
    • 2017-04-07
    • 2019-01-01
    相关资源
    最近更新 更多