首页 > 解决方案 > 在 C 中使用 sprintf 时出现意外的数组行为

问题描述

apply 后我面临着奇怪的行为sprintflist[0]似乎刚刚消失,结果strlenis 0。然后我尝试申请strcpystrlen达到预期并返回3。所以我的问题是为什么sprintf会抹去我的,如果我坚持申请,我list[0]该如何恢复价值?提前致谢。list[0]sprintf

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

void main() {
    char list[5][7] = { "One", "Two", "Three", "Four", "Five" };    
    char item[7];

    int i = 0;

    for (i = 0; i < 5; i++) {
        sprintf(item, "%-7s", list[i]);
        //strcpy(item, list[i]);
    }

    printf("%d", strlen(list[0]));
}

标签: carrays

解决方案


您的代码具有未定义的行为,因为%-7s目标数组中至少需要 8 个字节:左对齐字符串为 7 个字节,空终止符为 1 个字节。请注意,如果任何字符串的长度超过 7 个字节,则目标数组中将需要更多空间。

这个错误可以解释观察到的行为:sprintf向 写入 8 个字节item,即一个字节太多,如果数组list在 结束后在内存中开始item,它的第一个字节将被空字节覆盖,导致list[0]被截断并成为长度为 0 的空字符串。

您应该使用snprintf它来防止缓冲区溢出并使您的数组至少有 8 个字节长。

另请注意,main它的返回类型为int.

这是修改后的版本:

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

int main() {
    char list[5][7] = { "One", "Two", "Three", "Four", "Five" };    
    char item[8];

    for (int i = 0; i < 5; i++) {
        snprintf(item, sizeof item, "%-7s", list[i]);
    }
    printf("%d\n", strlen(list[0]));
    return 0;
}

推荐阅读