This question already has answers here:
How can I read and parse CSV files in C++?
(39 answers)
Closed 2 years ago.
I have a code that reads a file with a following:
word1,word2,word,3....,word8
word1,word2,word,3....,word8
word1,word2,word,3....,word8
ifstream infile;
//string path;s
infile.open("file.csv");
string line;
CourseNode *current = head;
int i=1;
if(infile.is_open()){
while(getline(infile, line)) {
if(i == 1)
cout << "1st line==> "+line << endl; // ignore first line
else { // read data
string firstname, lastname, id, a,b,c,d,t ;
stringstream sst(line);
getline(getline (sst, firstname, ','),lastname, ',');
//getline(getline(getline (sst, firstname, ','),lastname, ','),id, ',');
cout << "result==> "<< firstname<<" "<<lastname << endl;
}
i++;
}
I assume i have to work with this line and insert there my string variables but i am not sure how!
getline(getline (sst, firstname, ','),lastname, ',');
Any help will be appreciateed! Thank you!
To read a .csv file you may read the entire line and split after to load easly your data:
std::ifstream infile;
infile.open("file.csv");
std::string line;
int i = 1;
if(infile.is_open()){
while(getline(infile, line)) {
if(i == 1) {
// ignore line
continue;
} else { // read data
std::vector<std::string> value; // this is where you stock the data
value = split(line); // add your implementation of split
// here: do something with the data in value
}
i++;
}
}
You have in value every data from a line of your .cvs file. Now, you can assigne every case to a specific variable or put them in a list of object.
Related
This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 2 years ago.
I am having a bit of trouble on reading data in a specific format into different variables. I need to read the data from the file and store into 5 different variables of different variable types.(string Name, string Fish, string Location, float Length, float Weight)
The format of the Data I am trying to store is as follows:
Picture of How Data is Stored in File
I have no issues obtaining the name, fish, and location from the file using the getline() function. My issue comes with the length and width.
ifstream file("test.txt");
while(file.good())
{
getline(file, Name);
getline(file, Species);
getline(file, Location);
file >> Length;
file >> Weight;
cout << Name << "\n" << Species << "\n" <<Location << "\n" <<Length << "\n";
}
When I use the following code the output becomes wonky and it prints the data out of order after the first listing. Any help with this would be greatly appreciated.
ifstream file("test.txt");
while (file) {
getline(file, Name);
getline(file, Species);
getline(file, Location);
file >> Length;
file >> Weight;
if (file) {
cout << Name << "\n" << Species << "\n" <<Location << "\n" <<Length << "\n";
// add this to skip the 2 newlines before reading the next string
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
else {
throw "Invalid input";
}
}
I'm trying to read a CSV file that looks like this:screenshot of a CSV file
When i read a line that says "Cliente" I want to skip it and read the next line. When i read a line "Itinerarios" I also want to skip it and read all the lines untill the next "Cliente" line. Basically Cliente is a class and Itinerario is a different class that is associated with Cliente, that's why i'm trying to read it that way.
I tried using ss.ignore() in this context but it seems to do nothing: My line is still "Cliente" and the code cant extract the values.
if (fe.good()) {
while (!fe.eof()) {
getline(fe, linea);
stringstream ss;
if (linea != "") {
++total;
if (total > 2) {
if (linea == "Cliente") {
ss << linea;
ss.ignore(20,'\n');
// Starts reading Cliente stuff
getline(ss, dni, ';');
getline(ss, pass, ';');
EDIT: Here's a reduced example:
int main(int argc, char** argv) {
ifstream fe;
string linea;
int total = 0; // Counts lines
string dni;
//Reads the file
fe.open("ClientesItinerarios.csv");
if (fe.good()) {
while (!fe.eof()) {
getline(fe, linea); //Toma una l�nea del fichero
stringstream ss;
if (linea != "") {
++total;
if (total > 2) {
if (linea == "Cliente") {
ss << linea;
ss.ignore(20,'\n');
// Read only the first value to make the example shorter
getline(ss, dni, ';'); //Stores the first part into dni
}
}
}
}
fe.close();
} else {
cerr << "Cannot read file" << endl;
}
return 0;
}
and if it helps heres a screenshot of my debugger when its over getline(ss, dni, ';');
This question already has answers here:
Easiest way to convert int to string in C++
(30 answers)
Converting Input string to float/double C++
(5 answers)
Closed 5 years ago.
How can I rewrite my readDetails function without using stod() or strtod() in C++?
The compiler I will be using doesn't have c++11 enabled and I get
'stod' was not declared in this scope error
int readDetails(SmallRestaurant sr[])
{
//Declaration
ifstream inf;
//Open file
inf.open("pop_density.txt");
//Check condition
if (!inf)
{
//Display
cout << "Input file is not found!" << endl;
//Pause
system("pause");
//Exit on failure
exit(EXIT_FAILURE);
}
//Declarations and initializations
string fLine;
int counter = 0;
int loc = -1;
//Read
getline(inf, fLine);
//Loop
while (inf)
{
//File read
loc = fLine.find('|');
sr[counter].nameInFile = fLine.substr(0, loc);
fLine = fLine.substr(loc + 1);
loc = fLine.find('|');
sr[counter].areaInFile = stod(fLine.substr(0, loc)); //line using stod
fLine = fLine.substr(loc + 1);
loc = fLine.find('|');
sr[counter].popInFile = stoi(fLine.substr(0, loc));
fLine = fLine.substr(loc + 1);
sr[counter].densityInFile = stod(fLine); //line using stod
counter++;
getline(inf, fLine);
}
//Return
return counter;
}
Below is the text I am trying to read:
Census Tract 201, Autauga County, Alabama|9.84473419420788|1808|183.651479494869
Census Tract 202, Autauga County, Alabama|3.34583234555866|2355|703.860730836106
Census Tract 203, Autauga County, Alabama|5.35750339330735|3057|570.60159846447
Use std::istringstream.
std::string number_as_text("123");
int value;
std::istringstream number_stream(number_as_text);
number_stream >> value;
Edit 2: For those pedantic people:
The example below reads a double. Very similar pattern to the above reading of an integer.
std::string number_as_text("3.14159");
double pi;
std::istringstream number_stream(number_as_text);
number_stream >> pi;
You could also use a variant of sprintf.
Edit 1: Another parsing method
You could try:
std::string tract;
std::string county;
std::string state;
double value1;
char separator;
//...
std::ifstream input("myfile.txt");
//...
std::getline(input, tract, ',');
std::getline(input, county, ',');
std::getline(input, state, '|');
input >> value1;
input >> separator;
//...
input.ignore(100000, '\n'); // Ignore any remaining characters on the line
The above doesn't require separate string to number conversion.
How do I read in lines from a file and assign specific segments of that line to the information in structs? And how can I stop at a blank line, then continue again until end of file is reached?
Background: I am building a program that will take an input file, read in information, and use double hashing for that information to be put in the correct index of the hashtable.
Suppose I have the struct:
struct Data
{
string city;
string state;
string zipCode;
};
But the lines in the file are in the following format:
20
85086,Phoenix,Arizona
56065,Minneapolis,Minnesota
85281
56065
I cannot seem to figure this out. I am having a really hard time reading in the file. The first line is basically the size of the hash table to be constructed. The next blank line should be ignored. Then the next two lines are information that should go into the struct and be hashed into the hash table. Then another blank line should be ignored. And finally, the last two lines are input that need to be matched to see if they exist in the hash table or not. So in this case, 85281 is not found. While 56065 is found.
This is what I have and it doesn't seem to be doing what I want it to do:
int main(int argc, char *argv[])
{
string str;
//first line of file is size of hashtable
getline(cin, str);
stringstream ss(str);
int hashSize;
ss >> hashSize;
//construct hash table
Location *hashTable = new Location[hashSize];
//skip next line
getline(cin, str);
string blank = " ";
while(getline(cin, str))
{
{
//next lines are data
Location locate;
string line;
getline(cin, line);
istringstream is(line);
getline(is, locate.zipCode, ',');
getline(is, locate.city, ',');
getline(is, locate.state, ',');
insertElementIntoHash(hashTable, locate, hashSize);
}
}
dispHashTable(hashTable, hashSize);
//read third set of lines that check if the zipCodes are in the hashtable or not
while(getline(cin, str))
{
//stop reading at a blank line or in this case, end of file
stringstream is(str);
string searchZipCode;
is >> searchZipCode;
searchElementInHash(hashTable, hashSize, searchZipCode);
}
//delete hash table after use
delete []hashTable;
return 0;
}
You might read the input this way:
#include <iostream>
#include <sstream>
#include <vector>
struct Location
{
std::string city;
std::string state;
std::string zipCode;
};
int main(int argc, char *argv[]) {
std::istringstream input(
"2\n"
"\n"
"85086,Phoenix,Arizona\n"
"56065,Minneapolis,Minnesota\n"
"\n"
"85281\n"
"56065\n"
);
// Make the size unsigned, to avoid signed/unsigned compare warnings.
unsigned hashSize;
std::string line;
getline(input, line);
std::istringstream hash_line(line);
// Ignore white space.
if( ! (hash_line >> hashSize >> std::ws && hash_line.eof())) {
std::cerr << "Error: Invalid file format [1].\n" << line << '\n';
return -1;
}
else {
getline(input, line);
std::istringstream first_blank_line(line);
// Ignore white space.
first_blank_line >> std::ws;
if( ! first_blank_line.eof()) {
// Missing blank line.
std::cerr << "Error: Invalid file format [2].\n" << line << '\n';
return -2;
}
else {
// Have a local variable (No need to allocate it)
// (Is it a hash table !???)
std::vector<Location> hashTable;
hashTable.reserve(hashSize);
while(hashTable.size() < hashSize && getline(input, line)) {
std::istringstream data_line(line);
Location locate;
getline(data_line, locate.zipCode, ',');
getline(data_line, locate.city, ',');
getline(data_line, locate.state); // Note: No comma here.
if(data_line && data_line.eof()) {
// Note: The fields may have leading and/or trailing white space.
std::cout
<< "Insert the location into the hash table.\n"
<< locate.zipCode << '\n'
<< locate.city << '\n'
<< locate.state << '\n';
hashTable.push_back(locate);
}
else {
std::cerr << "Error: Invalid file format [3].\n" << line << '\n';
return -3;
}
}
if(hashTable.size() != hashSize) {
std::cerr << "Error: Invalid file format [4].\n";
return -4;
}
else {
getline(input, line);
std::istringstream second_blank_line(line);
// Ignore white space.
second_blank_line >> std::ws;
if( ! second_blank_line.eof()) {
// Missing blank line.
std::cerr << "Error: Invalid file format [5].\n";
return -5;
}
else {
std::string searchZipCode;
while(input >> searchZipCode) {
// Search element in the hash table
}
}
}
}
}
return 0;
}
Following modification should work:
//skip next line
getline(cin, str);
string blank = " ";
string line;
while(getline(cin, line) && (line != ""))
{
{
//next lines are data
Location locate;
istringstream is(line);
getline(is, locate.zipCode, ',');
getline(is, locate.city, ',');
getline(is, locate.state, ',');
insertElementIntoHash(hashTable, locate, hashSize);
}
}
I know this post has been made before on stack overflow, and I have combined various tutorials; but why does this code cause an error on execution - it does compile.
void leaderBoard::loadFromFile(void)
{
string line;
ifstream leaderBoardFile ("leaderboard.data");
vector<string> playerInfoVector;
if (leaderBoardFile.is_open())
{
while ( leaderBoardFile.good() )
{
playerInfoVector.clear();
getline (leaderBoardFile,line);
std::string input = line;
std::istringstream ss(input);
std::string token;
//cout << line << endl;
while(getline(ss, token, ',')) {
//for current line;
playerInfoVector.push_back(token);
}
string firstName = playerInfoVector.at(0);
string stringAge = playerInfoVector.at(1);
string stringScore = playerInfoVector.at(2);
//int age;
//stringstream(stringAge) >> age;
//int score;
//stringstream(stringScore) >> score;
//addScore(firstName,age,score);
////stringstream(stringAge) >> age;
////Add text to vector (push back)
playerInfoVector.clear();
}
leaderBoardFile.close();
}
else cout << "Unable to open file";
}
Yes loads of times
while ( leaderBoardFile.good() )
{
playerInfoVector.clear();
getline (leaderBoardFile,line);
should be
while ( getline (leaderBoardFile,line) )
{
playerInfoVector.clear();
It is incredible how many times this error is repeated. You actually got it right in your second while loop, so why wrong in the first one?
Unfortunately some tutorials also get this wrong.
It would also be sensible to add a check that you really do have three items in your vector. Something like this
if (playerInfoVector.size() < 3)
{
cerr << "Not enough items in player info vector\n";
exit(1);
}
string firstName = playerInfoVector.at(0);
string stringAge = playerInfoVector.at(1);
string stringScore = playerInfoVector.at(2);