use ifstream with a string instead of a file in c++? - c++

ifstream has nice tools for parsing files, such as << which work in loops and can consume floats, ints, or whatever you want into variables (as long as your variable types match what you are trying to consume with <<. I want to know if, instead of:
ifstream myReadFile;
myReadFile.open(some_file); // open the file
float x;
int y;
// some_file = "0.5 5"
myReadFile >> x >> y;
If I can somehow get a string object that is identical to some_file into ifstream. What I want to do is:
ifstream myReadFile;
myReadFile = my_string
...
Essentially parsing files is easy with ifstreams but parsing strings in c++ is a PITA (compared to say, Python).

Use std::stringstream:
// Initialize contents of the stream with your string
std::stringstream myReadString(my_string);
float x;
int y;
// Use the stream just like an fstream
// my_string = "0.5 5"
myReadString >> x >> y;

erm, you might want to look at stringstream.

Related

Extract data from c++ string

I wanted to extract the values from the string in C++. I guess this is not the C++ way of doing this, but that one in particular doesn't work. Any ideas?
string line = "{10}{20}Hello World!";
int start;
int end;
string text;
// What to use here? Is the sscanf() a good idea? How to implement it?
cout << start; // 10
cout << end; // 20
cout << text; // Hello World!
Although you can make sscanf work, this solution is more appropriate for C programs. In C++ you should prefer string stream:
string s("{10}{20}Hello World!");
stringstream iss(s);
Now you can use the familiar stream operations for reading input into integers and strings:
string a;
int x, y;
iss.ignore(1, '{');
iss >> x;
iss.ignore(1, '}');
iss.ignore(1, '{');
iss >> y;
iss.ignore(1, '}');
getline(iss, a);
Demo.
You could use the method String.find() to get the positions of '{' and '}' and then extract the data you want through String.substr().
text does not need to have an "&" in front of it inside the sscanf, since string names are already pointers to their starting address.
sscanf(line, "{%d}{%d}%s", &start, &end, text);

ignore to the n° whitespace with ifstream

I have a data file with a lot of columns of doubles but I want to read only two of them with a while loop
double x, y;
ifstream in;
double foo;
while( in >> foo ) {
in >> foo;
in >> foo;
...
in >> x;
in >> y;
... something with x and y
}
Two questions
1) There is a way to do the same thing without a fake double foo?
2) there is a way to do that without repeat in >> foo (or a for loop) like stream to the n° whitespace with a one-line code? There is a built-in function to skip to the n° whitespace?
What I would suggest instead is to read an entire row in a string and use a stringstream to manipulate it or just use something like find_last_of functions from the string class itself to pick out the last two columns and then convert it back to a double.

Reading/parsing text file input c++

A little background: I am working on a sliding block puzzle for a school project and this is our first using C++ instead of Java. This is the first time I have had to implement something that reads data from a file.
I have a simple question regarding reading input from a text file.
I understand how to read the file line by line and hold each line in a string, I want to know if I can parse the string into different data types as the file is read.
Currently I am reading each line and storing them as strings in a vector for parsing later, and I know there must be a much simpler way to implement this
The first line holds 2 integers which will indicate the length and width of the grid, the following lines will have 4 integers and a char for use as arguments when creating the blocks.
My question is this, if I read the file character by character instead, is there a function I can use that will detect if the character is an integer or a char (and ignore the spaces) so I can store them immediately and create the block objects as the file is read? How would i deal with integers >10 in this case?
EDIT: Just noting I am using fstream to read the files, I am unfamiliar with other input methods
A sample input:
4 4
3 1 2 1 b
1 1 1 1 a
To detect whether a piece of string can be parsed as an integer, you just have to parse it and see if you succeed. The best function for that would probably be std::strtoul(), since it can be made to tell you how many characters it consumed, so that you can continue parsing after that. (See the man page for details.)
However, if you already know the format of your file, you can use iostream formatted extraction. This is quite straightforward:
#include <fstream>
std::ifstream infile("thefile.txt");
int n1, n2, x1, x2, x3, x4;
char c;
if (!(infile >> n1 >> n2)) { /* error, could not read first line! Abort. */ }
while (infile >> x1 >> x2 >> x3 >> x4 >> c)
{
// successfully extracted one line, data is in x1, ..., x4, c.
}
Another alternative is to read every line into a string (using std::getline), then creating a stringstream from that line, and parsing the stringstream with >>. This has the added benefit that you can discover and skip bad lines and recover, while in the direct formatted extraction I presented above, you cannot recover from any error.
If you can assert each type, I suggest using stream operators, like you would with cin.
#include <fstream>
using namespace std;
int main()
{
fstream fileStream;
fileStream.open("inputfile.txt");
int firstNumber;
fileStream >> firstNumber;
char firstChar;
fileStream >> firstChar;
}
This way, you can read by value, instead of reading by line and then parsing the line. Just read in every value you need into a variable, as you discover you need it, like that.
I would read each line into a string (as you have been doing).
Then I would read the tokens from that line into the appropriate variables.
The operator>> when applied to a stream will convert the next value in a stream into the correct type. If this is not possable it sets flags on the stream indicating failure that are easy to test.
int x;
stream >> x; // ignores white space then: reads an integer from the stream into x
char c;
stream >> c; // ignores white space then: reads an char from the stream into c
double d;
stream >> d; // ignores white space then: reads an double from the stream into d
Assuming your input:
4 4
3 1 2 1 b
1 1 1 1 a
Not knowing what the the values mean I will put my assumptions in comments.
// Assume that stream is a std::fstream already opened to you file.
std::string line1;
std::getline(stream, line1); // reads "4 4" into `line1`
std::stringstream line1stream(line1); // convert line1 into a stream for reading.
int a;
int b;
line1stream >> a >> b; // reads "4 4" from 'line1' into a (now 4) b (now 4)
if (!stream || !line1stream)
{
// failed reading the first line.
// either reading the line failed (!stream)
// or reading 2 integers from line1stream failed (!line1stream)
throw SomeException("Failed");
}
std::string line2;
std::getline(stream, line2); // reads "3 1 2 1 b" into line2
std::stringstream line2stream(line2); // convers line2 into a stream for reading.
int data[4];
char c;
line2stream >> data[0] >> data[1] >> data[2] >> data[3] >> c;
if (!stream || !line2stream)
{
// failed reading the second line.
// either reading the line failed (!stream)
// or reading 4 integers and one char from line2stream failed (!line2stream)
throw SomeException("Failed");
}
ifstreams are also istreams, so you can use the same operator >> as with std::cin.
int main()
{
std::ifstream s("test.txt");
if (s.is_open())
{
int i, j, k;
s >> i >> j >> k;
}
}
Note that this is way not the fastest way of parsing, but that is probably irrelevant to you.

How to read integer value from file in C++

How can read integer value from file? For example, these value present in a file:
5 6 7
If I open the file using fstream then how I can get integer value?
How can read that number and avoid blank space?
ifstream file;
file.open("text.txt");
int i;
while (file >> i) {
cout << i << endl;
}
ifstream f(filename);
int x, y, z;
f >> x >> y >> z;
ifstream f;
f.open("text.txt");
if (!f.is_open())
return;
std::vector<int> numbers;
int i;
while (f >> i) {
numbers.push_back(i);
}
It's really rare that anyone reads a file Byte by Byte ! ( one char has the size of one Byte).
One of the reason is that I/O operation are slowest. So do your IO once (reading or writing on/to the disk), then parse your data in memory as often and fastly as you want.
ifstream inoutfile;
inoutfile.open(filename)
std::string strFileContent;
if(inoutfile)
{
inoutfile >> strFileContent; // only one I/O
}
std::cout << strFileContent; // this is also one I/O
and if you want to parse strFileContent you can access it as an array of chars this ways: strFileContent.c_str()

How to read in a double from a file in c++

How do you read in a double from a file in C++?
For ints I know you can use the getline() and then atoi, but I am not finding an array to double function. What is available for reading in doubles, or converting a char array to a double?
You can use stream extraction:
std::ifstream ifs(...);
double d;
ifs >> d;
This work provided that other then whitespace, the next data in the stream should be a double in textual representation.
After the extraction, you can check the state of the stream to see if there were errors:
ifs >> d;
if (!ifs)
{
// the double extraction failed
}
Do not consider using atof(), or any of the ato.. functions, as they do not allow you to diagnose errors. Take a look at strtod and strtol. Or use the stream extraction operators.
I'm wondering, does one need to be careful about locale settings (e.g. a locale could use comma instead of dot to separate the decimal part) or do stringstreams always default to some standard "C locale" notation?
You can leverage istringstream For example, here are toDouble and toInt:
double toDouble(string s) {
double r = 0;
istringstream ss(s);
ss >> r;
return r;
}
int toInt(string s) {
int r=0;
istringstream ss(s);
ss >> r;
return r;
}