【发布时间】:2021-10-18 23:55:58
【问题描述】:
如何在 C 中的 Linux 上将文件读入字符串? 我想出了一些代码,但它不起作用,我知道为什么。 fgetc() 总是返回 -1。
文件结构是这样的
.:
Files/
main.c
makefile
./Files:
test
main.c的内容:
#include <stdio.h>
int fileLength(const char filePath[]);
void readFile(const char filePath[], char* outString);
int main()
{
char fileContents[fileLength("Files/test")];
readFile("Files/test", &fileContents);
printf("DEBUG: Address of fileContents is 0x%x\n", &fileContents);
printf("File contents:\n%s\n", fileContents);
return 0;
}
int fileLength(const char filePath[])
{
//Open the file
FILE* file;
if ((file = fopen(filePath, "r")) == NULL)
{
printf("ERROR: File (%s) cannot be opened.\n", filePath);
return -1;
}
//Find the length
fseek(file, 0, SEEK_END);
return ftell(file);
}
void readFile(const char filePath[], char* outString)
{
FILE* file;
//File reading
printf("DEBUG: File path is %s\n", filePath);
if ((file = fopen(filePath, "r")) == NULL)
{
printf("ERROR: File (%s) cannot be opened.\n", filePath);
exit(1);
}
//Get length of file and allocate the according amount of memory
fseek(file, 0, SEEK_END);
int fileLength = ftell(file);
printf("DEBUG: File length is %i\n", fileLength);
//Allocate string
char fileContent[fileLength];
//Read file to string
printf("DEBUG: File contents as digits:\n");
for (int i = 0; i < fileLength; i++)
{
fileContent[i] = fgetc(file);
printf("%d ", fileContent[i]);
}
printf("\n");
printf("DEBUG: Contents of file are:\n%s\n", fileContent);
fclose(file);
printf("DEBUG: outString is pointing to 0x%x\n", outString);
*outString = fileContent;
}
输出通常只是一堆问号菱形的东西(在终端中运行),它们与文件的长度相匹配,最后还有一些其他随机字符。每次运行程序时,末尾的字符都会改变。
【问题讨论】:
-
fseek(file, 0, SEEK_END);使文件指针位于文件末尾。这就是fgetc失败的原因。获取文件长度后再次调用rewind或fopen文件。另外,请注意fileLength函数会导致资源泄漏,因为它不会fclose文件。 -
另外,
char fileContent[fileLength];最终不是一个有效的字符串,因为它不是 NUL 终止的。使其大一个字节,并确保最后一个字节设置为 0。 -
您需要查看整个代码 - 您使用 fileLength 来获取大小,但 readFile 无论如何都会做同样的事情 - 并且实际上不会将读取的内容发送回 main()。此外,您永远不会关闭您打开的任何文件。
-
我按照 kaylum 所说的做了,调试打印有效,但 main() 中的“文件内容:\n%s\n”没有,我的作业有问题吗?
-
*outString = fileContent;不会像您认为的那样做。事实上,编译器应该警告你。您不应该创建本地fileContent数组。改为直接写入outString。