c++ 从fstream阅读单个字符?

mbyulnm0  于 2023-01-22  发布在  其他
关注(0)|答案(6)|浏览(144)

我尝试从stdio转换到iostream,这被证明是非常困难的,我已经掌握了加载文件和关闭它们的基本知识,但是我真的不知道什么是流,或者它们是如何工作的。
在stdio中,与此相比,一切都相对简单和直接。我需要做的是
1.从文本文件中读取单个字符。
1.根据字符的内容调用函数。
1.重复直到我读完文件中的所有字符。
目前为止我知道的不多

int main()
{
    std::ifstream("sometextfile.txt", std::ios::in);
    // this is SUPPOSED to be the while loop for reading.  I got here and realized I have 
    //no idea how to even read a file
    while()
    {
    }
return 0;
}

我需要知道的是如何得到一个字符,以及这个字符实际上是如何存储的(它是字符串?整型?字符型?我能自己决定如何存储它吗?)
一旦我知道了,我想我就可以处理剩下的了,我会把字符存储在一个合适的容器中,然后使用一个开关根据字符的实际情况来做一些事情,它看起来像这样。

int main()
{
    std::ifstream textFile("sometextfile.txt", std::ios::in);

    while(..able to read?)
    {
        char/int/string readItem;
        //this is where the fstream would get the character and I assume stick it into readItem?
        switch(readItem)
        {
        case 1:
            //dosomething
              break;
        case ' ':
            //dosomething etc etc
              break;
        case '\n':
        }
    }
return 0;
}

注意,我需要能够检查白色和新行,希望这是可能的。如果不是一个泛型容器,我可以在int中存储数字,在char中存储字符,这也会很方便。如果不是这样,我可以解决它。
感谢任何人谁可以向我解释如何流的工作和什么都是可能的。

cwtwac6a

cwtwac6a1#

如果你想使用任何算法,你也可以抽象出用streambuf_iterator s得到单个字符的整个概念:

#include <iterator>
#include <fstream>

int main(){
  typedef std::istreambuf_iterator<char> buf_iter;
  std::fstream file("name");
  for(buf_iter i(file), e; i != e; ++i){
    char c = *i;
  }
}
dsekswqp

dsekswqp2#

您也可以使用标准的for_each算法:

#include <iterator>
#include <algorithm>
#include <fstream>

void handleChar(const char& c)
{
    switch (c) {
        case 'a': // do something
            break;
        case 'b': // do something else
            break;
        // etc.
    }
}

int main()
{
    std::ifstream file("file.txt");
    if (file)
        std::for_each(std::istream_iterator<char>(file),
                      std::istream_iterator<char>(),
                      handleChar);
    else {
        // couldn't open the file
    }
}

istream_iterator跳过空白字符。如果这些字符在文件中有意义,请改用istreambuf_iterator

yuvru6vn

yuvru6vn3#

这个问题已经得到了解答,但是不管怎样,你可以使用comma operator来创建一个循环,它的行为类似于for each循环,它遍历整个文件,逐个读取每个字符,并在完成时停止。

char c;
while((file.get(c), file.eof()) == false){
    /*Your switch statement with c*/
}
    • 说明**:for循环(file.get(c), file.eof())中表达式的第一部分的功能如下:首先执行file.get(c),读取一个字符并将结果存储在c中。然后,由于逗号操作符,返回值被丢弃,并执行file. eof(),无论是否到达文件末尾,都返回一个bool。然后比较该值。
    • 旁注:**ifstream::get()总是读取下一个字符。这意味着调用它两次将读取文件中的前两个字符。
dxpyg8gm

dxpyg8gm4#

fstream::get
下次你有类似的问题,去cplusplusreference或类似的网站,找到你有问题的class,并阅读每一种方法的描述。通常情况下,这会解决问题。谷歌搜索也有效。

k97glaaz

k97glaaz5#

老实说,我在这里尽量避免使用迭代器,因为它只会损害可读性。相反,考虑一下:

int main()
{
    std::ifstream file("sometextfile.txt")

    char c;
    while(file >> c) {
        // do something with c
    }
    // file reached EOF
    return 0;
}

这样做是因为流实现了operator bool,如果流没有到达EOF,则可以隐式转换为true,如果流到达EOF,则可以隐式转换为false;并且因为file >> c返回文件本身,所以它可以用作while条件。
只有在打算使用中的其他函数时,使用迭代器才真正有用,但对于普通的阅读,使用流运算符更简单、更容易读取。

m0rkklqb

m0rkklqb6#

while (textFile.good()) {
  char a;
  textFile.get(a);
   switch(a)
        {
        case 1:
            //dosomething
              break;
        case ' ':
            //dosomething etc etc
              break;
        case '\n':
    }
}

相关问题