问题
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
- Read a single character from a text file.
- Call a function based on what that character is.
- 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.
回答1:
You also can abstract away the whole idea of getting a single character with streambuf_iterator
s, 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;
}
}
回答2:
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.
回答3:
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.
回答4:
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.
回答5:
while (textFile.good()) {
char a;
textFile.get(a);
switch(a)
{
case 1:
//dosomething
break;
case ' ':
//dosomething etc etc
break;
case '\n':
}
}
来源:https://stackoverflow.com/questions/9176867/reading-a-single-character-from-an-fstream