C从函数返回const char指针或char指针

时间:2016-02-27 15:15:43

标签: c arrays string pointers const

我想更好地理解这一点,所以我在这里问。我编写了一个函数来读取文件并将内容作为字符串返回。它目前被实现为返回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;
}

1 个答案:

答案 0 :(得分:2)

在评论中已经解释了一些我不会重复的错误,但我建议你尽快修复。
现在,您必须在键入定义时考虑内部和外部数据对数据的预期或必需行为 在您的情况下,您需要在函数内部使用可更改的数据缓冲区,但外部需要一个不可更改的数据缓冲区。澄清这一点,你可以输入函数,然后使用强制转换:

const char *get_resource(const char** InRes, const char* filename)
{
    char *res;
    size_t count = ((strlen(resource_dir) + strlen(filename) + 1));
    if (*InRes)
    {
        res = realloc((void *)*InRes, count * sizeof(char));
        if (!res)
            return NULL;
    }
    else
    {
        res = calloc(count, sizeof(char));
        if (!res)
            return NULL;
    }
    *InRes = res;
    strcpy(res, resource_dir);
    strcat(res, filename);
    return res;
}

关于不需要强制转换的返回的注意事项,因为使const数据不会违反数据性质,反之亦然(例如,生成可更改的常量数据)。