显示问题的测试工具。
此代码与 OP 的不同之处在于始终显示errno 的状态。
当内存不足时,errno 被设置,但getline() 返回的长度超过了capacity - 很奇怪 - 而不是 -1。
如果这符合与否,我留给您对以下内容的解释。 IMO 不符合要求。如果由于getline() 以及ferror() 之外的任何原因设置了errno,我希望返回值为-1,或者在文件末尾没有读取。
我怀疑这个问题是由于内存分配延迟造成的。
返回值
成功时,getline() 和 getdelim() 返回读取的字符数,包括分隔符,但不包括终止空字节 ('\0')。该值可用于处理读取的行中嵌入的空字节。
两个函数都在读取行失败时返回 -1(包括文件结束条件)。如果发生错误,设置 errno 以指示原因。
错误
EINVAL 错误参数(n 或 lineptr 为 NULL,或流无效)。
ENOMEM 分配或重新分配行缓冲区失败。
代码还对 CR/LF 与 LF 进行了实验,但这似乎并不相关。
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
int djtest(unsigned sh, unsigned long long a, bool crflag) {
printf("sh:%2u a:%12llu crlf:%d ", sh, a, crflag);
FILE *stream = fopen("test.bin", "wb");
if (stream == NULL) {
return printf("error fopen(wb)\n");
}
char buf[1024 * 1204];
memset(buf, 'a', sizeof buf);
while (a > 0) {
unsigned long long m = a;
if (m > sizeof buf) m = sizeof buf;
size_t y = fwrite(buf, sizeof *buf, (size_t) m, stream);
if (y != m) {
return printf("error fwrite\n");
}
a -= m;
}
if (fputs(crflag ? "\r\n" : "\n", stream)) {
return printf("error fputs\n");
}
if (fclose(stream)) {
return printf("error fclose\n");
}
stream = fopen("test.bin", "r");
if (stream == NULL) {
return printf("error fopen(r)\n");
}
char* line = NULL;
size_t capacity = 0;
ssize_t n = getline(&line, &capacity, stream);
int err = errno;
printf("cap:%12zu ssize_t:%12lld feof:%d ferror:%d errno:%2d line:%p %s ", //
capacity, (long long)n, feof(stream), ferror(stream), err, (void*)line, strerror(err));
free(line);
if (fclose(stream)) {
return printf("error fclose\n");
}
return printf("Fin\n");
}
int main() {
for (unsigned sh = 28; sh < 31; sh++) {
unsigned long long a = 1ull << sh;
djtest(sh, a, 0);
djtest(sh, a, 1);
fflush(stdout);
a *= 2;
}
printf("All done\n");
return 0;
}
输出
sh:28 a: 268435456 crlf:0 cap: 536870912 ssize_t: 268435457 feof:0 ferror:0 errno: 0 line:0xbff20008 No error Fin
sh:28 a: 268435456 crlf:1 cap: 536870912 ssize_t: 268435458 feof:0 ferror:0 errno: 0 line:0xbff20008 No error Fin
sh:29 a: 536870912 crlf:0 cap: 1073741824 ssize_t: 536870913 feof:0 ferror:0 errno: 0 line:0x1ff80008 No error Fin
sh:29 a: 536870912 crlf:1 cap: 1073741824 ssize_t: 536870914 feof:0 ferror:0 errno: 0 line:0x1ff80008 No error Fin
sh:30 a: 1073741824 crlf:0 cap: 1073741824 ssize_t: 1610088455 feof:0 ferror:0 errno:12 line:0x1ff80008 Cannot allocate memory Fin
sh:30 a: 1073741824 crlf:1 cap: 1073741824 ssize_t: 1610088455 feof:0 ferror:0 errno:12 line:0x1ff80008 Cannot allocate memory Fin
All done
GNU C11 (GCC) 版本 6.4.0