Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading a single character from an fstream?

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.

like image 397
Jcrack Avatar asked Feb 07 '12 13:02

Jcrack


People also ask

How do you read a single character in C++?

If you prefer to read one character at a time (including whitespace characters), you can use the get operation: char ch; while (inFile. get(c)) { ... } In this example, each time the while loop condition is evaluated, the next character in the input file is read into variable ch.

Is get () C++?

C++ gets() The gets() function in C++ reads characters from stdin and stores them until a newline character is found or end of file occurs.


4 Answers

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.

like image 68
batburger Avatar answered Nov 06 '22 08:11

batburger


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.

like image 23
jrok Avatar answered Nov 06 '22 08:11

jrok


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;
  }
}
like image 32
Xeo Avatar answered Nov 06 '22 07:11

Xeo


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.

like image 26
SigTerm Avatar answered Nov 06 '22 09:11

SigTerm