Splitting input string based on whitespace and commas
This will do the job.
if (inFile.is_open()){
cout << "test" << endl;
//Read until no more lines in text file to read
while (getline(inFile, instruction))
{
istringstream ss(instruction);
string token;
//Separate string based on commas and white spaces
getline(ss,token,' ');
myString.push_back(token);
cout << myString[i] << endl;
i++;
while (getline(ss, token,',')){
ss.ignore();
myString.push_back(token);
cout << myString[i] << endl;
i++;
}
}
}
Points:
getline(inFile,instruction)
will get you entire line
getline(ss,token,' ')
reads till white space
getline(ss,token,',')
reads till comma
finally, ss.ignore()
, to ignore a character in stream.
It is important to note that, getline
stops if End of Stream is reached.
Your inFile>>instruction
reads till while space by default. To read the entire line, you have to use getline instead.
Noobgineer
Updated on June 04, 2022Comments
-
Noobgineer almost 2 years
I am reading in formatted lines from a file and need to parse it and output some results to a file. The trouble i am having is properly parsing the input to deal with whitespaces and commas. The format of lines in the file can be of the following:
a r3, r2, r1 ah r8, r5, r6, r7 ai r10, i10, r127
So i can have have 4-5 different elements in the line. The first element is a "command", then a whitespace, then the values that are separated with commas and whitespaces.
My current implementation is the following:
#include <iostream> #include <string> #include <fstream> #include <sstream> #include <vector> #include <bitset> using namespace std; void main() { string instruction; vector<string> myString; ifstream inFile; inFile.open("myfile.txt"); int i = 0; if (inFile.is_open()){ cout << "test" << endl; //Read until no more lines in text file to read //while (getline(inFile, instruction)) while (inFile >> instruction) { istringstream ss(instruction); string token; //Separate string based on commas and white spaces while (getline(ss, token,',')){ //getline(token, token, ' '); //Push each token to the vector myString.push_back(token); cout << myString[i] << endl; i++; } } } system("pause"); }
But this does not work. If i test it with
a r3, r2, r1
, i only geta
and the program stops reading since it sees the white space.The other version i tried is to change the reading of the file to
while (getline(inFile, instruction))
, but then this splits my string into:a r3 r1 r2
It thinks a(space)r3 is one element. Its splitting the entire line correctly, based on the commas, but the initial read is incorrect since i need it to also split a and r3. How can i do this?
-
Noobgineer about 8 yearsI dont see how this will help my problem because all it is returning the number of times it had to search until it found the particular string. I need to do this with the assumption of a format, as opposed to specific content. I.e., i dont know what characters/string it will be, but i only know the format.
-
xaxxon about 8 yearsI misread a bit... in that case, just search for the first space, then split on commas after the location of the first space. It just requires two parts. std::string::find will be useful for that.
-
xaxxon about 8 yearswill that get the last bit after the last comma?
-
Noobgineer about 8 years@Rishit The output results in a r3 1 2. So it removed the r's from r1 and r2 (which is good cuz i needed to do this anyways), but not from r3. Why doesnt it remove r from r3?
-
Noobgineer about 8 yearsNever mind. It was my mistake in the file formatting.
-
Rishit Sanmukhani about 8 years@xaxxon Yes, it will. I have checked it on my system.
getline
will read till the end of stream is reached or delimiter is reached. So it doesn't matter if we have comma at the end of line, because stream ends there. -
Rishit Sanmukhani about 8 years@Noobgineer If you don't have spaces in your file, it will ignore the first character, which is why you will be getting r3 1 2. You can tinker with it now!