我有此功能,它读取一些.txt文件的第一行并返回该行供我使用。我不知道行将要走多久,所以我不能有恒定大小的缓冲区。 我的问题是我不能使用此功能,因为它不是我的代码,它会被视为作弊(我有考试)。
我一直在考虑数组的可变长度,但这是邪恶的,因为有人对我说,我可以将整行扫描到我猜的某个地方,但是我不确定在这种情况下我会怎么做(我需要返回行)
char* readLine(FILE *line) {
char individualChar;
int pos = 0;
int size = 16;
char *buffer = (char *)malloc(size);
while ((individualChar = fgetc(line)) != EOF && individualChar != '\n'){
if (pos + 1 == size){
size *= 2;
char *tmp = (char *)realloc(buffer, size);
if (!tmp){
free(buffer);
fprintf(stderr, "Realloc failed");
return 0;
}
buffer = tmp;
}
buffer[pos] = individualChar;
pos++;
}
buffer[pos] = '\0';
return buffer;
}
答案 0 :(得分:2)
在这里张贴很多代码是不好的,因为OP具有
因为它不是我的代码,所以被视为作弊(我参加考试)。
一些技巧
我不知道行将要走多久,所以我不能保持恒定的缓冲区大小。
防御性编程假定合理合理的上限以防止黑客利用。 IAC,读取文本文件会导致环境限制。
环境限制
一个实现应支持包含至少254个字符的行的文本文件,包括终止换行符。宏BUFSIZ
的值至少应为256。C11§7.21.27
采用这种方法:
#include <stdio.h>
#define SANE_BOUND (BUFSIZ+1)
char* readLine(FILE *line) {
char buffer[SANE_BOUND];
if (fgets(buffer, sizeof buffer, line) == NULL) {
return NULL;
}
return strdup(buffer);
}
如何简化此
readLine()
函数?
要清楚,您不想复制的代码有问题。
更正
// char is insufficient to distinguish the 257 different results from fgetc()
// char individualChar;
int individualChar;
// Use size_t for sizing, `int` may be too small
size_t pos = 0;
size_t size = 16;
由于罕见的输入错误,如果第一个fgetc()
调用返回EOF
或以后的调用返回EOF
,则该函数应返回NULL
。
丢弃演员,不需要。
//char *buffer = (char *)malloc(size);
//char *tmp = (char *)realloc(buffer, size);
char *buffer = malloc(size);
char *tmp = realloc(buffer, size);
为什么检查不完整?
代码中有if (!tmp){
,但尚未对if (!buffer){
进行事先检查
次要
// Use \n and stay case correct
// fprintf(stderr, "Realloc failed");
fprintf(stderr, "realloc() failed\n");
pedantic
size *= 2;
可能溢出。您想要多安全?
设计
我要合适的大小并加上最后一个realloc()
。
我将重新设计以将读取的大小和分配的内存都传达给调用方。文本文件 lines 可能不包含 null字符,并且仅返回 string 指针并不表示某些内容被读取。也适用于此case。
分配readLine()
的好比OP发布的代码要简单。
答案 1 :(得分:0)
您可以采用一种更简单的方法:
此代码不是最佳选择,因为它两次读取文件,但是我认为 适合您的操作会更简单:
#include <stdio.h>
#include <stdlib.h>
char *readline(FILE *f)
{
size_t size = 0;
char *ret = NULL;
long pos = ftell(f);
/* find line size */
int c = fgetc(f);
while (c != EOF && c != '\n')
{
c = fgetc(f);
++size;
}
if (size)
{
/* allocate mem */
ret = malloc(size + 1);
/* rewind file */
fseek(f, SEEK_SET, pos);
/* read data */
fread(ret, 1, size, f);
/* add string limiter */
ret[size] = 0;
}
return ret;
}
警告
此代码不完整,因为它无法测试:
f
不是NULL
malloc
和fread
的返回值