getdelim报告的无效参数

时间:2014-11-10 03:12:48

标签: c linux gnu getline errno

我尝试使用getdelim函数将整个文本文件的内容读入字符串。

以下是我正在使用的代码:

ssize_t bytesRead = getdelim(&buffer, 0, '\0', fp);

但是失败了,strerror(errno)说"错误:参数无效"

我已经查看了所有可以使用的文档,并且无法使其正常工作,我已经尝试过getline,但是我希望这项功能更适合。

缓冲区也是NULL初始化,所以它似乎不是那个 fp也没有报告任何错误,文件打开完美

编辑:我的实现基于此stackoverflow问题Easiest way to get file's contents in C

的答案

1 个答案:

答案 0 :(得分:2)

Kervate,请为gcc启用编译器警告(-Wall),并注意它们。他们很有帮助;为什么不接受你能得到的所有帮助?

正如WhozCraig和上午所指出的那样。在对原始问题的评论中,getdelim() man page显示了正确的用法。

如果您想阅读由NUL字符分隔的记录,可以使用

FILE   *input; /* Or, say, stdin */
char   *buffer = NULL;
size_t  size = 0;
ssize_t length;

while (1) {
    length = getdelim(&buffer, &size, '\0', input);
    if (length == (ssize_t)-1)
        break;

    /* buffer has length chars, including the trailing '\0' */
}

free(buffer);
buffer = NULL;
size = 0;

if (ferror(input) || !feof(input)) {
    /* Error reading input, or some other reason
     * that caused an early break out of the loop. */
}

如果要将文件内容读入单个字符数组,则getdelim()功能错误。

相反,使用realloc()动态分配和增长缓冲区,使用fread()附加到缓冲区。为了帮助您入门 - 这还不完整! - 考虑以下代码:

FILE   *input; /* Handle to the file to read, assumed already open */
char   *buffer = NULL;
size_t  size = 0;
size_t  used = 0;
size_t  more;

while (1) {

    /* Grow buffer when less than 500 bytes of space. */
    if (used + 500 >= size) {
        size_t new_size = used + 30000; /* Allocate 30000 bytes more. */
        char  *new_buffer;

        new_buffer = realloc(buffer, new_size);
        if (!new_buffer) {
            free(buffer); /* Old buffer still exists; release it. */
            buffer = NULL;
            size = 0;
            used = 0;
            fprintf(stderr, "Not enough memory to read file.\n");
            exit(EXIT_FAILURE);
        }

        buffer = new_buffer;
        size = new_size;
    }

    /* Try reading more data, as much as fits in buffer. */
    more = fread(buffer + used, 1, size - used, input);
    if (more == 0)
        break; /* Could be end of file, could be error */

    used += more;
}

请注意,后一个代码段中的buffer不是字符串。没有终止NUL字符,所以它只是一个字符数组。实际上,如果文件包含二进制数据,则该数组可能包含许多NUL(\0,零字节)。假设没有错误并且所有文件都已被读取(您需要检查该文件,请参阅前一个示例),buffer包含从文件中读取的used个字符,并为{{分配了足够的空间1}}。如果是size,那么used > 0。如果size > used,则used == 0可能为零,也可能不为零。

如果要将size转换为字符串,则需要决定如何处理可能嵌入的buffer字节 - 我建议将其转换为例如空格或制表符,或移动数据以完全跳过它们 - 并在末尾添加字符串终止\0以使其成为有效字符串。