gpt4 book ai didi

c - 在 C 中安全地打印结构的所有属性

转载 作者:行者123 更新时间:2023-12-02 08:35:15 25 4
gpt4 key购买 nike

我正在编写一个 toString 方法,该方法打印出指向结构的输入指针的所有属性。在阅读处理字符串的安全方法时,我最终创建了以下解决方案:请注意,Person 结构具有名称、体重、高度和年龄属性(除名称之外的所有整数,名称是一个字符数组)。

char* toString(struct Person* inputPerson)
{
// Allocate memory to return string
char* ret = malloc(sizeof (char) * 100);
// copy "Name: " into string
strcpy(ret, "Name: ");
// safely copy name, at most leaving enough room for the other params (leaving 50 bytes)
strncat(ret, inputPerson->name, 100-50);
// copy "Age: " into string
strcat(ret, "\n\tAge: ");
// create tmp char to allow us to convert ints age, weight, and height into strings
char tmp[4];
// safely convert string to int (max number of digits being 3)
snprintf(tmp, sizeof(tmp), "%d", inputPerson->age);
// safely copy at most 3 characters, plus a null terminating char
strcat(ret, tmp); // the previous snprintf makes sure that tmp is not too large.
// repeat previous 2 steps for both weight and height attributes
strcat(ret, "\n\tWeight: ");
snprintf(tmp, sizeof(tmp), "%d", inputPerson->weight);
strcat(ret, tmp);
strcat(ret, "\n\tHeight: ");
snprintf(tmp, sizeof(tmp), "%d", inputPerson->height);
strcat(ret, tmp);

// Return a pointer to the string
return ret;
}

我的问题是:这是矫枉过正吗?我想做的就是安全可靠地打印出每个属性。对于每个字符串,我必须在附加之前确保它是最大大小。对于每个整数,我必须将它打印成一个字符串(确保最大允许长度),然后将该字符串附加到我的返回字符串中。有更简单的方法吗?每次我查看“100-50”代码部分时,我的 heebie jeebies 也在增长:如何指定“分配给 ret 的大小”而不是 100?

最佳答案

既然您正在 malloc 返回缓冲区,为什么不通过分配正确大小的缓冲区来让自己的生活更轻松呢?正如 Joachim 所建议的,您甚至可以使用 snprintf 来做到这一点:

char* toString(struct Person* inputPerson)
{
size_t space_required =
snprintf(0, 0,
"Name: %s\n"
"\tAge: %d\n"
"\tWeight: %d\n"
"\tHeight: %d\n",
inputPerson->name,
inputPerson->age,
inputPerson->weight,
inputPerson->height);

// space_required excludes the terminating NUL
// sizeof(char) == 1 *by definition*
char *ret = malloc(space_required+1);
if (!ret)
return 0;

snprintf(ret, space_required+1,
"Name: %s\n"
"\tAge: %d\n"
"\tWeight: %d\n"
"\tHeight: %d\n",
inputPerson->name,
inputPerson->age,
inputPerson->weight,
inputPerson->height);
return ret;
}

这可能看起来很重复。如果你的 C 库有 asprintf ,你可以避免重复:

char* toString(struct Person* inputPerson)
{
char *ret;
if (asprintf(&ret,
"Name: %s\n"
"\tAge: %d\n"
"\tWeight: %d\n"
"\tHeight: %d\n",
inputPerson->name,
inputPerson->age,
inputPerson->weight,
inputPerson->height) == -1)
return 0;
return ret;
}

如果您没有 asprintf,您可以使用mallocvsnprintf 来实现它。我会把它留作练习 ;-)

关于c - 在 C 中安全地打印结构的所有属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22414969/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com