所以我试图使用这个函数读取整个文本文件:
FILE *fp = fopen(path, "r");
fseek(fp, 0, SEEK_END);
int tamanioArchivo = sizeof(char) * ftell(fp);
fseek(fp, 0, SEEK_SET);
char* archivo = malloc(tamanioArchivo + 1);
fread(archivo, tamanioArchivo + 1, 1, fp);
//do something with archivo
fclose(fp);
free(archivo);
我调试了它,问题似乎在fread
行。它带回文件并在最后添加一些垃圾。有什么想法我做错了吗?
答案 0 :(得分:4)
通常C doesn't care文件的内容是什么。无论是文本还是二进制数据,它的读取方式都是一样的。这意味着如果你想读取一个字符串并获得一些很好的空终止的东西,你需要自己处理它。
fread(archivo, tamanioArchivo+1, 1, fp);
这会读取一个额外的字节(同样,空终止是一个C事件,文件系统不强制执行此操作)。摆脱加1.然后你必须确保它以空终止:
archivo[tamanioArchivo] = '\0';
答案 1 :(得分:1)
试试这个例子:
/* Open Fpga config file */
fpconf = fopen(file, "rb");
if (fpconf == NULL) {
return ERROR;
}
/* set SEEK_END to read the file size using ftell */
fseek(fpconf, 0L, SEEK_END);
bsize = ftell(fpconf);
print_dbg("Size of file: %d bytes\n", (int)bsize);
/* set file offset 0 */
fseek(fpconf, 0L, SEEK_SET);
data = (uint8_t *) malloc(sizeof(uint8_t) * bsize);
if (data == NULL) {
print_err("Error in malloc\n");
return ERROR;
}
/* Read data from file and store into buffer */
fread(data, bsize, 1, fpconf);
/* Close file */
fclose(fpconf);
答案 2 :(得分:1)
“垃圾”来自于不正确地检查/打印archivo
而代码没有注意到读了多少。
fread()
保存到archivo
数据中,但该数据肯定不是空字符终止 - 一个C 字符串。如果'\0'
指向字符串,则附加archivo
。
但是在哪里? 在最后一个字符读取后 - 由fread()
的返回值确定,不是在请求的字符数之后。
即使没有错误,由于"\r\n"
的文本模式行结束转换为"\n"
,返回值可能会少于请求的字符数。从ftell()
返回的值不一定是在文本模式下读取的字符数。
无需尝试阅读tamanioArchivo+1
个字符。使用tamanioArchivo
。
另请参阅@ Andrew Henle关于fread(ptr, element_size, number_of_elements, stream)
参数顺序的好评。
// Note that the file is opened in text mode, not binary mode
FILE *fp = fopen (path, "r");
fseek(fp, 0, SEEK_END);
// int tamanioArchivo = sizeof(char) * ftell(fp);
long tamanioArchivo = ftell(fp);
fseek(fp, 0, SEEK_SET); // or `rewind(fp);
// Good to allocate +1 for the null chracter
char* archivo = malloc(tamanioArchivo + 1u);
// Save the return value and drop the +1
// fread(archivo, tamanioArchivo+1, 1, fp);
size_t read_count = fread(archivo, 1, tamanioArchivo, fp);
// bad
// bytes read may be less than the offset due to CR/LF-->LF or input error
archivo[tamanioArchivo] = '\0';
// good
archivo[read_count] = '\0';
//do something with archivo
puts(archivo);
fclose (fp);
free(archivo);
强大的代码会检查fopen()
,malloc()
,fseek()
,ftell()
的返回值是否存在异常返回值。寻求最终,用于确定文件长度的ftell()
方法具有额外的限制。替代方案取决于各种未发布的编码目标。