读入文本文件 - 一次1个字符.用C

msc*_*ccc 2 c arrays text-files

我试图逐行读取文本文件并单独处理每个字符.

例如,我的文本文件中的一行可能如下所示: ABC XXXX XXXXXXXX ABC

行中总会有不同的空格.但是相同数量的字符(包括空格).

这就是我到目前为止......

char currentLine[100];
fgets(currentLine, 22, inputFile);
Run Code Online (Sandbox Code Playgroud)

然后我试图遍历currentLine数组并使用每个字符......

for (j = 0; j<22; j++) {
    if (&currentLine[j] == 'x') {
        // character is an x... do something
     }
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮我解决这个问题吗?

你可能会说 - 我刚刚开始使用C.

RBe*_*eig 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;
}
Run Code Online (Sandbox Code Playgroud)

请注意,c声明int,不是char因为它EOF具有与可以存储在a中的所有字符不同的值char.

对于更复杂的解析,一次读取一行文件通常是正确的方法.但是,您希望对未正确格式化的输入数据更加防御.从本质上讲,编写代码来假设外部世界是敌对的.永远不要假设文件完好无损,即使它是您刚写的文件.

例如,您使用100个字符的缓冲区来读取行,但将读取的数量限制为22个字符(可能是因为您知道22是"正确的"行长度).额外的缓冲区空间很好,但您应该考虑文件可能包含长度错误的行的可能性.即使这是一个错误,您还必须决定如何处理该错误并重新同步您的进程或放弃它.

编辑:我为规范的简单案例添加了一些假设其余程序的骨架.对于C的新用户,有几点需要指出.首先,我假设一个简单的命令行界面来获取要处理的文件的名称,并使用argc该参数进行验证确实存在.如果没有,我打印一条简短的用法消息,利用其中的内容argv[0]按惯例以某种有用的方式命名当前程序,并以非零状态退出.

我打开文件以便以文本模式阅读.文本和二进制模式之间的区别在Unix平台上并不重要,但在其他模式上尤为重要,尤其是Windows.由于讨论是一次处理文件一个字符,我假设文件是​​文本而不是二进制文件.如果fopen()失败,则返回NULL并将全局变量errno设置为描述失败原因的代码.perror()翻译的电话errno用于人类可读的东西并将其与提供的字符串一起打印.这里我提供了我们试图打开的文件的名称.结果看起来像"foo.txt:没有这样的文件".在这种情况下,我们也以非零状态退出.我没有打扰,但出于不同的原因退出具有不同的非零状态代码通常是明智的,这可以帮助shell脚本更好地理解错误.

最后,我关闭了文件.原则上,我也应该测试fclose()失败.对于只读取文件的进程,大多数错误条件已经被检测为某种内容错误,并且在结束时不会添加任何有用的状态.但是,对于文件写入,在调用之前,您可能不会发现某些I/O错误fclose().在编写文件时,最好检查返回代码,并期望在任何触及文件的调用中处理I/O错误.