我正在尝试逐行读取文本文件并单独处理每个字符。
例如,我的文本文件中的一行可能如下所示:
ABC XXXX XXXXXXXX ABC
行中总会有不同数量的空格。但是相同数量的字符(包括空格)。
这就是我到目前为止......
char currentLine[100];
fgets(currentLine, 22, inputFile);
然后我尝试遍历currentLine数组并使用每个字符......
for (j = 0; j<22; j++) {
if (¤tLine[j] == 'x') {
// character is an x... do something
}
}
任何人都可以帮我解决这个问题吗?
你可能会说 - 我刚刚开始使用C。
答案 0 :(得分:8)
以下是按字符处理文件的规范方法:
#include <stdio.h>
int main(int argc, char **argv)
{
FILE *fp;
int c;
if (argc != 2) {
fprintf(stderr, "Usage: %s file.txt\n", argv[0]);
exit(1);
}
if (!(fp = fopen(argv[1], "rt"))) {
perror(argv[1]);
exit(1);
}
while ((c = fgetc(fp)) != EOF) {
// now do something with each character, c.
}
fclose(fp);
return 0;
}
请注意,c
已声明为int
,而非char
,因为EOF
的值与可存储在char
中的所有字符不同
对于更复杂的解析,一次读取一行文件通常是正确的方法。但是,您希望对未正确格式化的输入数据更加防御。从本质上讲,编写代码来假设外部世界是敌对的。永远不要假设文件完好无损,即使它是您刚写的文件。
例如,您使用100个字符的缓冲区来读取行,但将读取的数量限制为22个字符(可能是因为您知道22是“正确的”行长度)。额外的缓冲区空间很好,但您应该考虑文件可能包含长度错误的行的可能性。即使这是一个错误,您还必须决定如何处理该错误并重新同步您的流程或放弃它。
编辑:我为规范的简单案例添加了一些假定的程序的骨架。对于C的新用户,有一些事情要指出。首先,我假设一个简单的命令行界面来获取要处理的文件的名称,并使用argc
验证参数是否真的存在。如果没有,我打印一个简短的用法消息,利用argv[0]
的内容按惯例以某种有用的方式命名当前程序,并以非零状态退出。
我打开文件以便以文本模式阅读。文本和二进制模式之间的区别在Unix平台上并不重要,但在其他模式上尤为重要,尤其是Windows。由于讨论是一次处理文件一个字符,我假设文件是文本而不是二进制文件。如果fopen()
失败,则返回NULL并将全局变量errno
设置为描述性代码,以解释失败的原因。对perror()
的调用将errno
翻译为人类可读的内容,并将其与提供的字符串一起打印出来。这里我提供了我们试图打开的文件的名称。结果看起来像“foo.txt:没有这样的文件”。在这种情况下,我们也以非零状态退出。我没有打扰过,但出于不同的原因退出不同的非零状态代码通常是明智的,这可以帮助shell脚本更好地理解错误。
最后,我关闭了文件。原则上,我还应该测试fclose()
的失败。对于只读取文件的进程,大多数错误条件已经被检测为某种内容错误,并且在结束时不会添加任何有用的状态。但是,对于文件写入,在调用fclose()
之前,您可能不会发现某些I / O错误。在编写文件时,最好检查返回代码,并期望在触摸文件的任何调用中处理I / O错误。
答案 1 :(得分:4)
您不需要地址运算符(&amp;)。你试图比较变量currentLine [j]和'x'的值,而不是它的地址。
答案 2 :(得分:1)
ABC XXXX XXXXXXXX ABC
有21个字符。还有换行符(22个字符)和终止空字节(23个字符)。
您需要fgets(currentLine, 23, inputFile);
才能阅读整行。
但是你将currentLine声明为100的数组。为什么不全部使用呢?
fgets(currentLine, sizeof currentLine, inputFile);
当使用所有这些时,并不意味着每次调用fgets
时系统都会放置多行。阅读fgets
后,'\n'
始终停止。
答案 3 :(得分:0)
尝试
while( fgets(currentLine, 100, inputFile) ) {
for (j = 0; j<22; j++) {
if (/*&*/currentLine[j] == 'x') { /* <--- without & */
// character is an x... do something
}
}
}