C语言 在 C 中逐字符读取文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4823177/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reading a file character by character in C
提问by Devan Buggay
Hey everyone, I'm writing a BF interpreter in C and I've run into a problem reading files. I used to use scanf in order to read the first string, but then you couldn't have spaces or comments in your BF code.
大家好,我正在用 C 编写 BF 解释器,但在读取文件时遇到了问题。我曾经使用 scanf 来读取第一个字符串,但是您的 BF 代码中不能有空格或注释。
Right now here is what I have.
现在这就是我所拥有的。
char *readFile(char *fileName)
{
FILE *file;
char *code = malloc(1000 * sizeof(char));
file = fopen(fileName, "r");
do
{
*code++ = (char)fgetc(file);
} while(*code != EOF);
return code;
}
I know the problem arises in how I'm assigning the next char in the file to the code pointer but I'm just not sure what that is.
My pointer knowledge is lacking which is the point of this exercise.
The interpreter works fine, all using pointers, I'm just having a problem reading files in to it.
我知道问题在于我如何将文件中的下一个字符分配给代码指针,但我不确定那是什么。
我的指针知识缺乏,这是本练习的重点。解释器工作正常,全部使用指针,我只是在读取文件时遇到问题。
(I'm going to implement only reading "+-><[].," into the file later, although if anyone has a good way to do it, it would be great if you'd let me know!)
(我将在稍后实现只读取“+-><[].,”到文件中,尽管如果有人有好的方法,如果你让我知道那就太好了!)
Thanks in advance
提前致谢
回答by dreamlax
There are a number of things wrong with your code:
您的代码有很多问题:
char *readFile(char *fileName)
{
FILE *file;
char *code = malloc(1000 * sizeof(char));
file = fopen(fileName, "r");
do
{
*code++ = (char)fgetc(file);
} while(*code != EOF);
return code;
}
- What if the file is greater than 1,000 bytes?
- You are increasing
codeeach time you read a character, and you returncodeback to the caller (even though it is no longer pointing at the first byte of the memory block as it was returned bymalloc). - You are casting the result of
fgetc(file)tochar. You need to check forEOFbefore casting the result tochar.
- 如果文件大于 1,000 字节怎么办?
code每次读取一个字符时都会增加,然后返回code给调用者(即使它不再指向由 返回的内存块的第一个字节malloc)。- 您正在将结果转换为
fgetc(file)tochar。您需要EOF在将结果转换为char.
It is important to maintain the original pointer returned by mallocso that you can free it later. If we disregard the file size, we can achieve this still with the following:
维护返回的原始指针很重要,malloc以便稍后可以释放它。如果我们不考虑文件大小,我们仍然可以通过以下方式实现:
char *readFile(char *fileName)
{
FILE *file = fopen(fileName, "r");
char *code;
size_t n = 0;
int c;
if (file == NULL)
return NULL; //could not open file
code = malloc(1000);
while ((c = fgetc(file)) != EOF)
{
code[n++] = (char) c;
}
// don't forget to terminate with the null character
code[n] = 'char *readFile(char *fileName) {
FILE *file = fopen(fileName, "r");
char *code;
size_t n = 0;
int c;
if (file == NULL) return NULL; //could not open file
fseek(file, 0, SEEK_END);
long f_size = ftell(file);
fseek(file, 0, SEEK_SET);
code = malloc(f_size);
while ((c = fgetc(file)) != EOF) {
code[n++] = (char)c;
}
code[n] = '#define BF_VALID "+-><[].,"
if (strchr(BF_VALID, c))
code[n++] = c;
';
return code;
}
';
return code;
}
There are various system calls that will give you the size of a file; a common one is stat.
有多种系统调用可以为您提供文件大小;一个常见的就是stat。
回答by Justin
Expanding upon the above code from @dreamlax
扩展@dreamlax的上述代码
char *readFile(char *fileName)
{
FILE *file;
char *code = malloc(1000 * sizeof(char));
char *p = code;
file = fopen(fileName, "r");
do
{
*p++ = (char)fgetc(file);
} while(*p != EOF);
*p = 'char *orig = code; // the beginning of the array
// ...
do {
*code = fgetc(file);
} while(*code++ != EOF);
*code = '##代码##'; // nul-terminate the string
return orig; // don't return a pointer to the end
';
return code;
}
char *readFile(char *fileName)
{
FILE *file;
int i = 0;
char *code = malloc(1000 * sizeof(char));
file = fopen(fileName, "r");
do
{
code[i++] = (char)fgetc(file);
} while(code[i-1] != EOF);
code[i] = '##代码##'
return code;
}
This gives you the length of the file, then proceeds to read it character by character.
这为您提供了文件的长度,然后继续逐个字符地读取它。
回答by caf
Here's one simple way to ignore everything but valid brainfwor characters:
这里有一种简单的方法可以忽略除有效的brainfwor字符之外的所有内容:
##代码##回答by Mandrake
the file is being opened and not closed for each call to the function also
每次调用该函数时,文件都被打开而不是关闭
回答by Oliver Charlesworth
I think the most significant problem is that you're incrementing codeas you read stuff in, and then returning the final value of code, i.e. you'll be returning a pointer to the endof the string. You probably want to make a copy of codebefore the loop, and return that instead.
我认为最重要的问题是您在code读取内容时递增,然后返回 的最终值code,即您将返回一个指向字符串末尾的指针。您可能想code在循环之前制作一个副本,然后返回它。
Also, C strings need to be null-terminated. You need to make sure that you place a '\0'directly after the final character that you read in.
此外,C 字符串需要以空字符结尾。您需要确保'\0'在您读入的最后一个字符之后直接放置一个。
Note:You could just use fgets()to get the entire line in one hit.
注意:您可以使用一fgets()键获取整行。
回答by Prav
Either of the two should do the trick -
两者中的任何一个都可以解决问题-
##代码##Like the other posters have pointed out, you need to ensure that the file size does not exceed 1000 characters. Also, remember to free the memory when you're done using it.
就像其他海报指出的那样,您需要确保文件大小不超过 1000 个字符。另外,请记住在使用完内存后释放内存。
回答by Chris Lutz
The problem here is twofold - a) you increment the pointer before you check the value read in, and b) you ignore the fact that fgetc() returns an int instead of a char.
这里的问题是双重的 - a) 在检查读入的值之前增加指针,b) 忽略 fgetc() 返回 int 而不是 char 的事实。
The first is easily fixed:
第一个很容易修复:
##代码##The second problem is more subtle - fgetc returns an int sonthat the EOF value can be distinguished from any possible chsr value. Fixing this uses a temporary int for the EOF check and probably a regular while loop instead of do / while.
第二个问题更微妙 - fgetc 返回一个 int 值,可以将 EOF 值与任何可能的 chsr 值区分开来。修复此问题使用临时 int 进行 EOF 检查,并且可能使用常规 while 循环而不是 do / while。

