【问题标题】:How to compute how much of my buffer is used (size) for write()?如何计算写入()使用了多少缓冲区(大小)?
【发布时间】:2015-03-30 05:10:02
【问题描述】:
char buf[256];
sprintf(buf, "It was %s\r\n", weather);
write(p->fd, buf, sizeof(buf));

上面的代码是一个大型项目的sn-p。

buf 用于保存多个不同长度的不同字符串。我怎么知道在 write 函数中放什么? sizeof() 只是给了256 我相信,因为 write 只会吐出一堆额外的垃圾字符。

【问题讨论】:

  • 您是否阅读了sprintf 上的文档?
  • 也许你想要strlen()
  • strlen() 正是我所需要的。谢谢!

标签: c


【解决方案1】:

使用len的代码版本应该是:

char buf[256];
int len = snprintf(buf, sizeof buf, "It was %s\r\n", weather);

if ( len < 0 || len >= sizeof buf )
     // error handling, abort...

write(p->fd, buf, len);

使用sprintf 是有风险的,因为如果weather 没有完全在您的控制之下,它可能会导致缓冲区溢出。

如其文档中所述,sprintf 系列如果出现错误可以返回负值;如果缓冲区不适合写入,则返回值可能大于缓冲区大小。

其他答案涵盖的另一个选项是省略检查len,而是使用strlen 来查找要发送的长度。有些人会认为这不必要地低效。此外,在这种情况下,您应该检查len,以防encoding fails 导致strlen 在垃圾上运行。

【讨论】:

    【解决方案2】:

    解决方案是 memset 和 strlen 或 sprintf 返回的组合

    char buf[256];
    memset(buf,'\0',sizeof(buf));
    sprintf(buf, "It was %s\r\n", weather);
    write(p->fd, buf, strlen(buf));
    

    char buf[256];
        memset(buf,'\0',sizeof(buf));
        int len = sprintf(buf, "It was %s\r\n", weather);
        write(p->fd, buf, len);
    

    【讨论】:

    • 我在 tutorialspoint.com 上看到了,但我不明白为什么我需要 memset
    • 因为在声明数组时,数组的所有索引都包含垃圾值。而且您不希望垃圾值影响您的功能。例如对于字符串,它们必须以 '\0' 字符结尾,以便 strlen() 正常工作。但是如果你不做 memset,终点会包含一些垃圾字符,strlen() 会给你错误的结果
    • memsetstrlen 版本中很有用,以防sprintf fails。这样strlen 就会找到0,而不是尝试读取未初始化的缓冲区。但是你只需要设置buf[0] = 0;,而不是全部。
    • @Yasir Majeed “如果你不做 memset,终点会包含一些垃圾”是不正确的。 sprintf() 将附加所需的'\0'。检查sprintf()的返回值以检测失败。
    【解决方案3】:

    你说得对,sizeof() 没有做你想做的事。

    您如何确定缓冲区中实际有多少有效数据取决于您如何将数据放在那里。在您的特定情况下,您可以使用sprintf() 的返回值,也可以在缓冲区上使用strlen()。我会推荐前者,因为sprintf() 无论您是否使用它都会返回该值。这些替代方案中的任何一个都将排除字符串的尾随空字节,因此如果您也想写入该空字节,请务必在长度上添加一个。

    如果您在其他地方通过其他方式填充缓冲区,那么确定要写入多少字节的适当机制可能会有所不同。

    【讨论】:

      猜你喜欢
      • 2012-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-06
      • 2013-05-13
      • 1970-01-01
      • 2012-02-06
      相关资源
      最近更新 更多