【问题标题】:confused with library function gets()与库函数 gets() 混淆
【发布时间】:2020-07-21 00:49:25
【问题描述】:

下面是库函数gets()的实现

// I know gets() can cause buffer overflow easily, just use this fuction for demo purpose

char *gets(char *s)
{
   int c;
   char *dest = s;

   while ((c = getchar()) != ’\n’ && c != EOF)
      *dest++ = c;
   if (c == EOF && dest == s)
      return NULL;
   *dest++ = ’\0’;
   return s;
}

void echo()
{
   char buf[8];
   gets(buf);
}

我有两个问题:

Q1-对于这条语句*dest++ = c;,我们知道后缀自增的优先级高于解引用,所以*dest++等价于*(dest++),但是我们不是丢失了第一个元素buf[0]吗?

Q2-为什么gets() 需要返回一个字符指针?返回指针与参数s 不一样吗?将gets() 方法签名设为:

void gets(char *s)

【问题讨论】:

  • gets() 的返回值对于错误检查很有用。详情请见this question
  • @JohnColeman 参数与返回的指针是同一个指针,用户应检查参数指针是否为空以进行错误检查
  • return NULL,但s从未设置为NULL
  • 我很高兴看到有关缓冲区溢出的评论,但我仍然要提到 gets 函数已从 2011 ISO C 标准的 C 库中删除。

标签: c


【解决方案1】:

Q1-对于这条语句*dest++ = c;,我们知道后缀自增的优先级高于解引用,所以*dest++等价于*(dest++),但不是我们丢了第一个元素buf[0]吗?

不,因为后增量返回变量的旧值,而不是增量值。所以我们取消引用原始的dest 值,然后增加它。相当于

*dest = c;
dest++;

如果是*(++dest) = c;你就对了

Q2-为什么gets() 需要返回一个char 指针?返回指针和参数 s 不一样吗?将 gets() 方法签名设置为:

返回值可以用来判断是否有错误。如果有错误,它会返回NULL

它可以被设计成返回一个整数状态。但设计者认为,如果返回值比这更有意义,那会更有用。

许多 C 字符串函数同样是多余的。例如,strcat()strcpy() 都返回目标字符串指针。

【讨论】:

    【解决方案2】:

    Q1-对于这个语句*dest++ = c;,我们知道后缀自增的优先级高于解引用,所以*dest++等价于*(dest++),但不是说我们丢失了第一个元素buf[0 ]?

    操作dest++将返回dest的值在操作之前

    Q2-为什么gets() 需要返回一个char 指针?返回指针和参数 s 不一样吗?将 gets() 方法签名设置为:

    你可以,但是你会丢失返回值给出的信息。如果返回一个 NULL 指针,那么你就知道发生了什么事。

    【讨论】:

    • 对于第二季度,用户在将参数传递给gets() 之前检查参数是否为空不是更合适。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    • 2012-09-20
    • 1970-01-01
    • 2016-04-08
    • 2014-08-05
    相关资源
    最近更新 更多