【发布时间】:2016-06-10 19:59:17
【问题描述】:
我想更好地理解这一点,所以我在这里问。我编写了一个读取文件并将内容作为字符串返回的函数。它目前被实现为返回char*,因为它看起来更容易,但我想知道这是否是正确的方法,因为许多使用char 数组的C 函数原型将它们作为const char 使用。我说它更容易的原因是,一旦你读取了所有数据,如果你想返回一个const char,我必须创建一个精确大小的新缓冲区并将数据复制到那里,而不是仅仅重新分配缓冲到正确的大小并返回在堆上分配的指针。
我的问题,返回值应该是const char* 还是char*?
这是一个小代码:
char *get_resource(char **res, const char *filename) {
size_t count = ((strlen(resource_dir) + strlen(filename) + 1));
*res = calloc(count, sizeof(char));
strncpy(*res, resource_dir, resource_dir_len);
strncat(*res, filename, strlen(filename));
return *res;
}
或者这个:
char *read_file(char **data, const char *file_path) {
FILE *fp;
size_t buffer = 4096;
size_t index = 0;
int ch;
fp = fopen(file_path, "r");
if (fp == NULL) {
printf("failed to open file: %s\n", file_path);
return "-1\0";
}
(*data) = calloc(buffer, sizeof(char));
while (EOF != (ch = fgetc(fp))) {
(*data)[index] = (char)ch;
++index;
if (index == buffer - 1) {
buffer = buffer * 2;
data = realloc(data, buffer);
if (data != NULL) {
printf("buffer not large enough, reallocating %zu bytes to "
"load %s\n",
buffer, file_path);
} else {
printf("failed to realloc %zu bytes to load %s\n", buffer,
file_path);
}
}
}
(*data) = realloc((*data), (sizeof(char) * (index + 1)));
(*data)[index] = '\0';
fclose(fp);
return *data;
}
【问题讨论】:
-
第二个代码的返回值应该是
const char*,因为函数可能会返回从字符串字面量转换而来的指针。 -
第一个代码 sn-p 错误地使用了
strncpy/strncat。strncat函数仅在第一个参数指向一个以 null 结尾的字符串时才有效,但strncpy不会像您使用它的方式那样为 null 终止(假设resource_dir_len == strlen(resource_dir))。建议不要使用strncpy,您可以使用strcpy或snprintf。 -
不要使用 strncpy 它不会像你想的那样。
-
为什么将指针返回到结果缓冲区两次:通过第一个参数和返回值?您可以将
char*传递给请求const char*的函数,但反之则不行。 (也许,我误解了你的问题。) -
我看到帖子说使用 strncpy 因为它更安全,然后我看到不使用 strncpy 因为它不是。有时这些事情有点难以跟上,从上面的粗体陈述来看,我认为我不应该使用它,所以我会改变它。 @MartinZabel 我这样做是为了可以连续进行多个函数调用。我传入返回的变量的原因是为了在执行行内函数时不会发生内存泄漏。
标签: c arrays string pointers constants