如何在C++中逐个字符地从文本文件中读取

30

我想知道怎么在C++中逐个字符地读取文本文件,这样我就能用一个while循环(只要还有文本剩余)来存储文档中的下一个字符到一个临时变量中,然后对其进行操作,并重复处理下一个字符。我知道如何打开文件等操作,但是temp = textFile.getchar()好像不起作用。

8个回答

57

你可以尝试类似这样的方法:

char ch;
fstream fin("file", fstream::in);
while (fin >> noskipws >> ch) {
    cout << ch; // Or whatever
}

3
@PeteBecker 是的,我喜欢它,因为这就是C读取单个字符时所做的。 - cnicutar
你放在那里的参数 noskipws 就是我要找的。 - Gabriel Arghire

14

@cnicutar和@Pete Becker已经指出了使用noskipws/取消skipws的可能性,以逐个字符读取输入中的空白字符。

另一个可能性是使用istreambuf_iterator来读取数据。除此之外,通常会使用像std::transform这样的标准算法来进行读取和处理。

例如,假设我们想要进行一种像凯撒密码一样的操作,从标准输入复制到标准输出,但对每个大写字母添加3,因此A会变成DB可以变成E等等(并且在结尾时,它会回绕,因此XYZ转换为ABC)。

如果我们要在C中执行该操作,通常会使用类似以下循环的代码:

int ch;
while (EOF != (ch = getchar())) {
    if (isupper(ch)) 
        ch = ((ch - 'A') +3) % 26 + 'A';
    putchar(ch);
}

如果要用C++做同样的事情,我可能会像这样更多地编写代码:

std::transform(std::istreambuf_iterator<char>(std::cin),
               std::istreambuf_iterator<char>(),
               std::ostreambuf_iterator<char>(std::cout),
               [](int ch) { return isupper(ch) ? ((ch - 'A') + 3) % 26 + 'A' : ch;});

通过这种方式执行任务,你将接收连续的字符作为传递给lambda函数的参数值(虽然你也可以使用显式的functor替代lambda函数)。


13

引用Bjarne Stroustrup的话:“>>运算符适用于格式化输入;也就是说,读取预期类型和格式的对象。如果这不是我们想要的,我们希望将字符读取为字符,然后对其进行检查,则使用get()函数。”

char c;
while (input.get(c))
{
    // do something with c
}

8

这里有一个C++的函数,可以帮助你逐个字符地读取文件。

void readCharFile(string &filePath) {
    ifstream in(filePath);
    char c;

    if(in.is_open()) {
        while(in.good()) {
            in.get(c);
            // Play with the data
        }
    }

    if(!in.eof() && in.fail())
        cout << "error reading " << filePath << endl;

    in.close();
}

5
    //Variables
    char END_OF_FILE = '#';
    char singleCharacter;

    //Get a character from the input file
    inFile.get(singleCharacter);

    //Read the file until it reaches #
    //When read pointer reads the # it will exit loop
    //This requires that you have a # sign as last character in your text file

    while (singleCharacter != END_OF_FILE)
    {
         cout << singleCharacter;
         inFile.get(singleCharacter);
    }

   //If you need to store each character, declare a variable and store it
   //in the while loop.

2

关于textFile.getch(),你是自己想出来的吗?还是有相关参考资料支持它能够工作?如果是后者,请删除该代码。如果是前者,请不要这样做,需要找到一个可靠的参考资料。

char ch;
textFile.unsetf(ios_base::skipws);
textFile >> ch;

是的。这就是为什么@cnicular使用了noskipws。我刚刚编辑了我的代码来修复这个问题。 - Pete Becker

1

在C++中使用C的<stdio.h>是没有理由不这样做的,事实上这通常是最优选择。

#include <stdio.h>

int
main()  // (void) not necessary in C++
{
    int c;
    while ((c = getchar()) != EOF) {
        // do something with 'c' here
    }
    return 0; // technically not necessary in C++ but still good style
}

2
旧线程等等。但问题是“来自文件”。您不能使用getchar从除标准输入之外的任何地方读取。您需要使用getc;并且您必须在某个地方打开文件指针。 - josaphatv

1
假设temp是一个char,而textFile是一个std::fstream的派生类...
你要找的语法是
textFile.get( temp );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接