c++ getline putting different parts of a line into variables [duplicate] - c++

This question already has answers here:
How can I read and parse CSV files in C++?
(39 answers)
Closed 5 years ago.
For the life of me, I can't seem to figure out how to do this properly.
First, I read a line from a csv file. Lets say, that line has
2992854,BOB,3452,394832
I don't want to read each result into a console like practically every example I've found, I want them to go in order, into these 4 variables:
int time;
string name;
int location;
int point;
Right now, this is my code:
string line;
ifstream inputFile("input.csv");
std::list<Cramista> Cramistas;
while (!inputFile.eof())
{
int time;
string name;
int location;
int point;
std::vector<std::string> stringArray;
std::size_t position = 0, found;
getline(inputFile, line);
while ((found = line.find_first_of(',', position)) != std::string::npos)
{
stringArray.push_back(line.substr(position, found - position));
position = found + 1;
}
time = stoi(stringArray[0]);
name = stringArray[1];
location = stoi(stringArray[2]);
point = stoi(stringArray[3]);
}
UPDATED:
So, with what I have here, I'm able to get the first 3 out of 4 pieces of the line, and put them into an array, which I can then move into variables. Trying to figure out how to get that 4th part.
I've got 2992854, BOB, and 3452 but I don't have 394832.

I mean basically in order to avoid "reading each result into the console" using
cin >> time >> name >> location >> point;
you would have to split the line by commas (assuming it's a string, then convert the non string data to integers.

Related

trying to give a variable to ifstream in c++ [duplicate]

This question already has answers here:
Put A String In A ifstream Method [duplicate]
(2 answers)
No matching function - ifstream open()
(1 answer)
Closed 3 years ago.
im new to c++ and trying to put a variable in this line : ifstream studentPaper(paper);
ill pass paper to this function and want to use it there. string paper has my files location (/name/file.txt)
if i put my file name there i dont get any errors = ifstream studentPaper("/name/file.txt");
but when i save my files location in to a string and give string to it ill get error = ifstream studentPaper(paper);
how can i do that without getting errors
void matchGrades(string paper) {
string aa= "asd";
ifstream studentPaper(paper);
ifstream base("base.txt");
int grade=3;
while ((!studentPaper.eof()) && (!base.eof())) {
string l1,l2;
getline(studentPaper,l1);
getline(base,l2);
if(l1==l2){
grade += 3;
} else {
grade -= 3;
}
}
studentPaper.close();
base.close();
cout << grade;
I think that You have to use removed string parameter "/name/file.txt" because parameter split space.
Try doing ifstream studentPaper(paper.c_str()).
Also if your file is located where your main.cpp is you won't need to specify the path. Something like this:
string studentFile = "student_file.txt";
Based on the information provided. If you are still getting an error please post it so that I can adjust my answer.

Is there a way to extract certain info from a string? c++

I need to read in some lines from a text file (amount of lines will be known during run time) but an example could be something like this:
Forecast.txt:
Day 0:S
Day 3:W
Day 17:N
My idea was to create a class which I did:
class weather
{
int day;
char letter;
};
Then create a vector of class as so:
vector<wather>forecast;
and now here is where I'm stuck. So I think I'd use a while loop?
id use my ifstream to read the info in and use a string to hold the information im reading in.
What I want to do is read in each line and extract the day number so in this example the 0, 3 and 15 and get the letter so S, W, N and store it in the vector of the class.
I was wondering if there's any way to do that? I could be coming at this wrong so forgive me im new to c++ and trying to figure this out.
Thank you for helping!
Your can use std::istringstream to parse each line, eg:
#include <sstream>
while (getline(in_s1, lines2))
{
istringstream iss(lines2);
string ignore1; // "Day"
char ignore2; // ":"
forecast f;
if (iss >> ignore1 >> f.day >> ignore2 >> f.letter)
weather.push_back(f);
}
Live Demo
Alternatively, you can parse each line using std::regex and related classes.
istringstream and the >> operator is probably the neatest C++ way to do it, as described in Remy's answer. In case you prefer to be a little less reliant on the stream magic and a bit more explicit, you can find the tokens you need and then extract them directly from the string.
Something like this:
while (getline(in_s1, lines2))
{
size_t startPos = lines2.find(' '); //get position of the space before the day
size_t endPos = lines2.find(':', startPos); //get position of the colon after the day
string day = lines2.substr (startPos+1, endPos-startPos-1); //extract the day
forecast f;
f.day = stoi(day); //stoi only supported since C++11, otherwise use atoi
f.letter = lines2[endPos+1];
weather.push_back(f);
}

How to read a comma delimited text file into arrays [duplicate]

This question already has answers here:
How do I iterate over the words of a string?
(84 answers)
How to use stringstream to separate comma separated strings [duplicate]
(2 answers)
Closed 8 months ago.
I have been working on this project and been reading in text files with ONLY spaces in between and not commas so I need to update how I read in the file into arrays. I have tried using stringstream() and getline() but no luck. Does anyone know how I can read in this file into arrays?
This is how I been doing it before
void readData(ifstream& inputFile, double lat[], double lon[], double yaw[], int& numLines)
{
// Read in headers.
string header;
getline(inputFile, header);
// Read in data and store in arrays.
for (int i = 0; i < numLines; i++)
{
if (inputFile >> lat[i])
{
inputFile >> lon[i];
inputFile >> yaw[i];
}
}
but Im not sure how to modify it to read in this type of file into arrays and also the only ones I'm interested in are
latitude
longitude
altitude(feet)
speed(mph)
gps
power
pitch
roll
yaw
motor on
834,,,,,,,,,,,,,,,,
latitude,longitude,altitude(feet),ascent(feet),speed(mph),distance(feet),max_altitude(feet),max_ascent(feet),max_speed(mph),max_distance(feet),time(millisecond),gps,power,pitch,roll,yaw,motor on
43.5803481,-116.7406331,0,0,0,0,0,0,0,0,539,10,97,178,180,141,0
43.5803481,-116.7406329,0,0,0,0,0,0,0,0,841,10,97,178,180,141,0
43.5803482,-116.7406328,0,0,0,0,0,0,0,0,1125,10,97,178,180,141,0
43.5803481,-116.7406329,-1,0,0,0,0,0,0,0,1420,10,97,178,180,141,0
43.580348,-116.7406328,0,0,0,0,0,0,0,0,1720,10,97,178,180,140,0
43.5803479,-116.7406326,-1,0,0,0,0,0,0,0,2023,10,97,178,180,140,0
43.5803478,-116.7406326,0,0,0,0,0,0,0,0,2344,10,97,178,180,140,0
43.5803476,-116.7406329,-1,0,0,0,0,0,0,0,2620,10,97,178,180,140,0
43.5803475,-116.7406329,-1,0,0,0,0,0,0,0,2922,10,97,178,180,140,0
43.5803473,-116.7406329,0,0,0,0,0,0,0,0,3221,10,97,178,180,140,0
If someone can point in the right direction that would be great. Thanks
You need to extract those commas, to the variable of type char:
std::ifstream f("d:\\temp\\z.txt");
string s;
double lat, lon, alt, asc, speed, dist, max;
vector<double> lat_vec, lon_vec, asc_vec, speed_vec, dist_vec, max_vec;
char c;
while (!f.eof()) {
f>>s; // get one line
stringstream st(s);
// below, eat first number, then comma, then second number, etc.
if (st>>lat>>c>>lon>>c>>alt>>c>>asc>>c>>speed>>c>>dist>>c>>max) {
lat_vec.push_back(lat); lon_vec.push_back(lon);
asc_vec.push_back(asc); speed_vec.push_back(speed);
dist_vec.push_back(dist); max_vec.push_back(max);
}
}
// if you really need arrays, not vectors
double *dist_ar = new double[dist_vec.size];
for (int i=0;i<dist_vec.size(); i++)
dist_ar[i]=dist_vec[i];
return 0;

Reading/parsing multiple INTs from a String

I've been reading about converting strings to integers, the "atoi" and "strol" C standard library functions, and a few other things I just can't seem to get my head around.
What I'm initially trying to do, is to get a series of numbers from a string and put them into an int array. Here is snippet of the string (there are multiple lines in the single string):
getldsscan
AngleInDegrees,DistInMM,Intensity,ErrorCodeHEX
0,0,0,8035
1,0,0,8035
2,1228,9,0
3,4560,5,0
...
230,1587,80,0
231,0,0,8035
232,1653,89,0
233,1690,105,0
234,0,0,8035
...
358,0,0,8035
359,0,0,8035
ROTATION_SPEED,4.99
The output is from my vacuum robot, a "Neato XV-21". I've gotten the output above from over a COM port connection and I've got it stored in a string currently. (As the robot can output various different things). In this example, I'm reading from a string neatoOutput which houses the output from the robot after I've requested an update from its laser scanner.
The "getldsscan" is the command I sent the robot, it's just being read back when I get the COM output so we skip over that. The next line is just helpful information about each of the values that is output, can skip over that. From then on the interesting data is output.
I'm trying to get the value of the Second number in each line of data. That number is the distance from the scanner to an obstacle. I want to have a nice tidy int distanceArray[360] which houses all the distance values that are reported back from the robot. The robot will output 360 values of distance.
I'm not fussed with error checking or reading the other values from each line of data yet, as I'll get them later once I've got my head around how to extract the current basic data I want. So far I could use something like:
int startIndex = 2 + neatoOutput.find("X",0); //Step past end of line character
So startIndex should give me the character index of where the data starts, but as you can see by the example above, the values of each number range in size from a single character up to 4 characters. So simply stepping forward through the string a set amount won't work.
What I'm thinking of doing is something like...
neatoOutput.find("\n",startIndex );
Which with a bit more code I should be able to parse one line at a time. But I'm still confused as to how I extract that second number in the line which is what I want.
If anyone is interested in about hacking/coding the robot, you can goto:-
http://www.neatorobotics.com/programmers-manual/
http://xv11hacking.wikispaces.com/
UPDATE: Resolved
Thanks for your help everyone, here is the code I'm going to work with in the near term. You'll notice I didn't end up needing to know the int startIndex variable I thought I would need to use.
//This is to check that we got data back
signed int dataValidCheck = neatoOutput.find("AngleInDegrees",0);
if (dataValidCheck == -1)
return;
istringstream iss(neatoOutput);
int angle, distance, intensity, errorCode;
string line;
//Read each line one by one, check to see if its a line that contains distance data
while (getline(iss,line))
{
if (line == "getldsscan\r")
continue;
if (line == "AngleInDegrees,DistInMM,Intensity,ErrorCodeHEX\r")
continue;
sscanf(line.c_str(),"%d,%d,%d,%d",&angle,&distance,&intensity,&errorCode); //TODO: Add error checking!
distanceArray[angle] = distance;
}
Try this (untested, so maybe minor bugs):
#include <iostream>
#include <sstream>
#include <string>
#include <cstdio>
using namespace std;
int main()
{
string s("3,2,6,4\n2,3,4,5\n");
istringstream iss(s);
int a, b, c, d;
string line;
while (getline(iss,line))
{
// Method 1: Using C
sscanf(line.c_str(),"%d,%d,%d,%d",&a,&b,&c,&d);
// Method 2: Using C++
std::stringstream lineStream(line);
char comma;
lineStream >> a >> comma >> b >> comma >> c >> comma >> d;
// do whatever
}
}
You may parse the string yourself. It's simple.
code:
int ParseResult(const char *in, int *out)
{
int next;
const char *p;
p = in;
next = 0;
while (1)
{
/* seek for next number */
for (; !*p && !isdigit(*p); ++p);
if (!*p)
break; /* we're done */
out[next++] = atoi(p); /* store the number */
/* looking for next non-digit char */
for (; !*p && isdigit(*p); ++p);
}
return next; /* return num numbers we found */
}

Reading delimited files in C++ [duplicate]

This question already has answers here:
How can I read and parse CSV files in C++?
(39 answers)
Closed 8 years ago.
What is the best way to read in a tab delimited file in C++ and store each line as a record? I have been looking for an open source library to help with this, but have been unsuccessful so it looks like I will have to write my own.
typedef vector<vector<string> > Rows;
Rows rows;
ifstream input("filename.csv");
char const row_delim = '\n';
char const field_delim = '\t';
for (string row; getline(input, row, row_delim); ) {
rows.push_back(Rows::value_type());
istringstream ss(row);
for (string field; getline(ss, field, field_delim); ) {
rows.back().push_back(field);
}
}
This will get you started. It doesn't do any checking that each row has the same number of fields, allow for escaping field_delim, etc.
There is no problem in using iostreams - you could read each line with getline into string, and then use stringstream on that string to iterate over fields.
There are a few libraries listed in wikipedia's article CSV_application_support.