Combine your solution with reading line by line, and with a little help of std::stringstream
:
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
int main() {
std::ifstream input{"input.txt"};
if(!input) {
std::cerr << "Failed to open the file\n";
return 1;
}
std::size_t line_number = 0;
std::istringstream stream{};
for(std::string line{}; std::getline(input, line); stream.clear()) {
stream.str(line);
std::size_t count = 0;
std::string number{};
while(std::getline(stream, number, ',')) {
++count;
}
std::cout << "Line " << line_number++ << " contains " << count << " digits\n";
}
}
After you make sure that the file was opened successfully, you can start processing the file.
First, pay attention to the for()
loop. We use a line
string to save a line read from the file. The condition of the loop is also the part where we read the line. std::getline
not only reads a line, but also returns the stream from where it was reading. That stream can be implicitely convered to bool
to check whether the stream is in a valid state. By doing that, we are reading the file line by line and making sure that if something goes wrong (i.e., we reach end of the file), we won't enter the loop and use, potentially corrupted, data. That's a big difference between using this method and !file.eof()
, which is almost always wrong.
Then, after reading a line, we initialize an std::istringstream
object with it. Stringstreams are useful helpers which enable us to operate on text as though it was a stream. We again use std::getline
, but this time to extract all the tokens separated by ','
.
The stream.clear()
part in necessary after we process a single line, because it clears all bad states of the stream (i.e., the state of reaching end of file - in our case, after reading the whole line).
We count the number of successfull extractions and display it on the screen.