从 fstream 读取单个字符?

发布于 2025-01-03 05:27:10 字数 1248 浏览 4 评论 0 原文

我正在尝试从 stdio 迁移到 iostream,事实证明这非常困难。我已经掌握了加载文件和关闭文件的基础知识,但我真的不知道流是什么,或者它们如何工作。

与此相比,在 stdio 中一切都相对简单和直接。我需要做的是

  1. 从文本文件中读取单个字符。
  2. 根据该字符的含义调用函数。
  3. 重复此操作,直到读完文件中的所有字符。

到目前为止我所拥有的是..不多:

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?char?我可以自己决定如何存储吗?)

一旦我知道我认为我可以处理剩下的事情。我会将角色存储在适当的容器中,然后使用开关根据该角色的实际情况执行操作。它看起来像这样。

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 中,而不是使用通用容器,那也会很方便。如果没有的话我可以解决它。

感谢任何可以向我解释流如何工作以及它们的可能性的人。

I'm trying to move from stdio to iostream, which is proving very difficult. I've got the basics of loading a file and closing them, but I really don't have a clue as to what a stream even is yet, or how they work.

In stdio everything's relatively easy and straight forward compared to this. What I need to be able to do is

  1. Read a single character from a text file.
  2. Call a function based on what that character is.
  3. Repeat till I've read all the characters in the file.

What I have so far is.. not much:

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;
}

What I need to know is how to get a single character and how that character is actually stored(Is it a string? An int? A char? Can I decide for myself how to store it?)

Once I know that I think I can handle the rest. I'll store the character in an appropriate container, then use a switch to do things based on what that character actually is. It'd look something like this.

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;
}

Notice that I need to be able to check for white space and new lines, hopefully it's possible. It would also be handy if instead of one generic container I could store numbers in an int and chars in a char. I can work around it if not though.

Thanks to anyone who can explain to me how streams work and what all is possible with them.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

悟红尘 2025-01-10 05:27:10

如果您想使用任何算法,您还可以抽象出使用streambuf_iterator获取单个字符的整个想法:

#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;
  }
}

You also can abstract away the whole idea of getting a single character with streambuf_iterators, if you want to use any algorithms:

#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;
  }
}
寄居人 2025-01-10 05:27:10

您还可以使用标准 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 。

You can also use standard for_each algorithm:

#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 skips whitespace characters. If those are meaningful in your file use istreambuf_iterator instead.

余生再见 2025-01-10 05:27:10

这已经得到了回答,但无论如何。
您可以使用 逗号运算符 创建一个循环,其行为类似于 foreach循环遍历整个文件,逐个读取每个字符,并在完成后停止。

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() 始终读取下一个字符。这意味着调用它两次将读取文件中的前两个字符。

This has already been answered but whatever.
You can use the comma operator to create a loop which behaves like a for each loop which goes through the entire file reads every character one by one and stop when it's done.

char c;
while((file.get(c), file.eof()) == false){
    /*Your switch statement with c*/
}

Explanation:
The first part of the expression in the for loop (file.get(c), file.eof())
will function as follows. Firstly file.get(c) gets executed which reads a character and stores the result in c. Then, due to the comma operator, the return value is discarded and file.eof() gets executed which returns a bool whether or not the end of the file has been reached. This value is then compared.

Side Note:
ifstream::get() always reads the next character. Which means calling it twice would read the first two character in the file.

星星的轨迹 2025-01-10 05:27:10

fstream::get

下次遇到类似问题时,请转到 cplusplusreference 或类似网站,找到 class 您遇到问题并阅读每个方法的说明。通常,这可以解决问题。谷歌搜索也有效。

fstream::get

Next time you have similar problem go to cplusplusreference or similar site, locate class you have problem with and read description of every method. Normally, this solves the problem. Googling also works.

落花浅忆 2025-01-10 05:27:10

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

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

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

这是可行的,因为流实现了运算符 bool,这使得如果流尚未达到 EOF,则可以隐式转换为 true,如果达到了,则可以隐式转换为 false;因为文件>> c 返回文件本身,它可以用作 while 条件。

仅当您打算使用 中的其他函数时,使用迭代器才真正有用,但对于普通阅读,使用流运算符更简单且更易于阅读。

I would honestly just avoid iterators here since it's just hurting readability. Instead, consider:

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

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

This works because the stream implements operator bool, which makes it implicitly convertible to true if the stream hasn't reached EOF, and false if it has; and because file >> c returns the file itself, it can be used as the while condition.

Using an iterator is only really useful if you intend to use other functions from , but for plain reading, using the stream operator is simpler and easier to read.

冬天旳寂寞 2025-01-10 05:27:10
while (textFile.good()) {
  char a;
  textFile.get(a);
   switch(a)
        {
        case 1:
            //dosomething
              break;
        case ' ':
            //dosomething etc etc
              break;
        case '\n':
    }
}
while (textFile.good()) {
  char a;
  textFile.get(a);
   switch(a)
        {
        case 1:
            //dosomething
              break;
        case ' ':
            //dosomething etc etc
              break;
        case '\n':
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文