【问题标题】:sprintf not functioning correctly when concatenating an int and string连接 int 和字符串时 sprintf 无法正常工作
【发布时间】:2015-12-04 01:09:31
【问题描述】:

我有以下代码(在服务器 [sender] 程序中):

#define PAYLOAD 256

//...some more code...

    int l;
    char packet[PAYLOAD];
    char seqNumNpacket[sizeof(l) + sizeof(packet) + 1]; //to account for the number, space and the packet

    FILE *fp2;
    fp2 = fopen(req, "r");
    l = 0;        
    char seqNumNpacket[sizeof(l) + sizeof(packet) + 1];
    //... some more code...
    n = fread(packet, 1, PAYLOAD, fp2);
    packet[n] = '\0';
    printf("%s", packet);
    sprintf(seqNumNpacket, "%d %s", l, packet);
    printf("%d %s", seqNumNpacket); //A

我在这里尝试从文件中读取字节,然后将其放在一个带有数字的字符串中,以便我可以使用 sendto()/recvfrom 将其发送到其他进程。

当我使用sprintf 将它们粘在一起时,问题就出现了。不知何故,而不是写一个时尚的字符串“seqNumpacket”它结束了“seqNumpacketseqNUm”。

我不知道是什么原因造成的,因此还没有找到解决它的方法。感谢您事先对这个愚蠢的问题提供帮助。

【问题讨论】:

  • sizeof(l) 与整数的 strnig 表示将具有的字符数无关。另外,不要将声明与语句混在一起,也不要在检查 fp2 == NULL 之前使用 fread()
  • 我这样做是因为默认情况下它是 4 个字节,这让我省去了尝试猜测 l 有多少个字符的麻烦,这使得连接时更容易。仍然不太确定这会如何改变事情。感谢其他关于编码风格的建议。
  • 我不明白你的评论,10000 可以用 32 位整数表示,并且它有超过 4 个字符,整数使用的字节数与字节数无关它的字符串表示将需要。
  • 如果你不知道要分配多少空间,你可以用snprintf代替sprintf,它会告诉你需要多少个字符。然后你可以分配缓冲区,然后用正确大小的缓冲区再次调用 snprintf。
  • 确切地说snprintf(NULL, 0, "%d %s", l, packet); 将返回您需要的字符数,没有'\0' 终止符,如果您在Linux 上,您可以使用asprintf(),它为目标字符串分配空间。

标签: c file printf


【解决方案1】:
  1. 你的代码最重要的问题是这个

    n = fread(packet, 1, PAYLOAD, fp2);
    

    即使你用对了,下一行

    packet[n] = '\0';
    

    可能是错误的,因为如果 n == PAYLOAD 这将在 packet 数组的末尾写入 1 个字节,您应该这样阅读

    n = fread(packet, 1, PAYLOAD - 1, fp2);
    

    如果您解决此问题,问题可能会消失,因为您的结果中似乎 packet 数组没有 '\0' 终止符。

  2. 第二个非常重要的问题是使用sizeof(int) 表示整数的字符串。

【讨论】:

  • 或者如果负载的完整大小可能很重要,则将缓冲区大小增加 1
  • @M.M 我想我可能会这样做@iharob 非常感谢。我使用asprintf 对它进行了相应的修改,它起作用了^_^ 可能与你同在。
猜你喜欢
  • 2017-01-22
  • 2016-08-12
  • 1970-01-01
  • 2017-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-02
  • 1970-01-01
相关资源
最近更新 更多