std::getline issue when parsing lines with stringstream library - c++

I am getting an error while trying to parse a stringstream when reading from a file, I cannot seem to figure what the issue is.
the error I am receiving is:
no matching function for call to 'getline'
std::getline(parse_input, intensity, ',');
this repeats for each variable I am trying to parse.
the following is my code:
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
int main(int argc, char const *argv[])
{
std::fstream fs;
fs.open("test.dat");
std::string* configuration_record;
std::string temp_count;
size_t no_of_records;
if(!fs.is_open())
{
std::cerr << "File failed to open" << std::endl;
}
else
{
while(!fs.eof())
{
std::getline(fs, temp_count);
no_of_records++;
}
fs.clear();
fs.seekp(0);
}
std::string stimulation_type;
std::string stimulation_name;
double intensity;
double frequency;
double duration;
std::string location;
configuration_record = new std::string[no_of_records];
for(size_t i=0; i<no_of_records; i++)
{
std::getline(fs, configuration_record[i]);
}
for(size_t i=0; i<no_of_records; i++)
{
size_t found;
found = configuration_record[i].find("stim");
if(found != std::string::npos)
{
std::stringstream parse_input(configuration_record[i]);
std::getline(parse_input, stimulation_type, ',');
std::getline(parse_input, stimulation_name, ',');
std::getline(parse_input, location, ',');
std::getline(parse_input, intensity, ',');
std::getline(parse_input, frequency, ',');
std::getline(parse_input, duration, ',');
std::cout << stimulation_name << "," <<location << intensity << "," << frequency << "," << duration
<< std::endl;
}
else
{
std::stringstream parse_input(configuration_record[i]);
std::getline(parse_input, stimulation_type, ',');
std::getline(parse_input, stimulation_name, ',');
std::getline(parse_input, intensity, ',');
std::getline(parse_input, duration, ',');
std::cout << stimulation_name << "," << intensity << "," << duration
<< std::endl;
}
}
return 0;
}

The declarations for getline from the manual are:
istream& getline (istream& is, string& str, char delim);
istream& getline (istream&& is, string& str, char delim);
istream& getline (istream& is, string& str);
istream& getline (istream&& is, string& str);
As you see, they accept an istream (stringstream is valid), however the second argument has to be a string, so when you pass double (intensity, frequency and duration), you are calling an inexistent function.
you can use a temporary string and then save it to a double, using stod:
std::string temp;
double intensity;
std::getline(parse_input, temp, ',');
intensity= std::stod (temp);

Related

Storing 4 values from each line from a txt file, into an object - C++

I'm wanting to take 4 values, each separated by a comma, and store them to a airport object. Each line would have those 4 values would be stored together. So, calling all objects from Sweden, would find all objects from the country sweden and retrieve the appropriate values as well. Right now I have 4 different vectors, which store all 4 object values, however, doesn't necessarily set all 4 attributes/values together as an object. Help is greatly appreciated.
Examples of what the Text File looks like -
1,Goroka,Goroka,Papua New Guinea,GKA,AYGA,-6.081689,145.391881,5282,10,U
2,Madang,Madang,Papua New Guinea,MAG,AYMD,-5.207083,145.7887,20,10,U
#include "pch.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
using namespace std;
struct Airport
{
string code;
string name;
string city;
string nation;
friend std::istream& operator>>(std::istream& input, Airport& a);
};
istream& operator>>(std::istream& input, Airport& a)
{
getline(input, a.code, ',');
getline(input, a.name, ',');
getline(input, a.city, ',');
getline(input, a.nation);
return input;
}
////////////////////////////////////////////
vector<string> split(const string& s, const string& delim)
{
const bool keep_empty = true;
vector<string> result;
if (delim.empty())
{
result.push_back(s);
return result;
}
string::const_iterator substart = s.begin(), subend;
while (true)
{
subend = search(substart, s.end(), delim.begin(), delim.end());
string temp(substart, subend);
if (keep_empty || !temp.empty())
{
result.push_back(temp);
}
if (subend == s.end())
{
break;
}
substart = subend + delim.size();
}
return result;
}
// Sorting Function
bool Sort_By_Name_Ascending(const Airport& a, const Airport& b)
{
return a.name < b.name;
}
int main()
{
vector<Airport> database;
Airport a;
char choice;
string chr;
ifstream inputFile;
inputFile.open("airports.dat");
if (!inputFile)
{
cout << "File Access Error!";
return 0;
}
string fileLine;
cout << "Reading File ..." << endl;
while (!inputFile.eof())
{
getline(inputFile, fileLine);
vector<string> lineVector = split(fileLine, ",");
if (lineVector[4].length() == 3)
{
while (inputFile >> a)
{
database.push_back(a);
}
}
}
cout << "What would you like to do?\nA. Sort in Alphabetical Order.\nB.
Delete an Airport.\nC. Exit Program." << endl;
cin >> choice;
switch (choice)
{
case 'A':
sort(database.begin(), database.end(), Sort_By_Name_Ascending);
break;
case 'B':
cout << "Deleting a value" << endl;
break;
case 'C':
return 0;
break;
}
return 0;
}
You may want to organize your data structures to model the input data:
struct Airport
{
std::string code;
std::string name;
std::string city;
std::string nation;
};
A next step is to overload operator>> to read in an instance from a stream:
struct Airport
{
//...
friend std::istream& operator>>(std::istream& input, Airport& a);
};
std::istream& operator>>(std::istream& input, Airport& a)
{
std::getline(input, a.code, ',');
std::getline(input, a.name, ',');
std::getline(input, a.city, ',');
std::getline(input, a.nation);
return input;
}
This simplifies the input:
std::vector<Airport> database;
Airport a;
while (inputfile >> a)
{
database.push_back(a);
}
To sort, you can come up with some functions or function objects and supply them to std::sort:
bool Sort_By_Name_Ascending(const Airport& a, const Airport& b)
{
return a.name < b.name;
}
//...
std::sort(database.begin(), database.end(), Sort_By_Name_Ascending);
Edit 1: The whole record or line
There is a difference between modeling the whole line versus only fields you are interested in. If your records are text line (one record == one text line), you may want to read in the text line as a string then extract the fields you are interested in.
std::istream& operator>>(std::istream& input, Airport& a)
{
std::string record;
std::getline(input, record);
// Now extract the interesting fields from the string.
std::istringstream record_stream;
unsigned int record_number;
char comma;
record_stream >> record_number; // Read but ignore.
record_stream >> comma; // Read but ignore.
std::getline(record_stream, a.code, ',');
std::getline(record_stream, a.name, ',');
std::getline(record_stream, a.city, ',');
std::getline(record_stream, a.nation);
return input;
}

C++ Validate Emails Via Substrings

I'm trying to take the profile info(username, email, etc.) from one directory and put it in another. I've been debugging the code for this program, and while there are no errors, the program won't run, saying that the program "has stopped working". I have already looked on this website and others for any possible answers, and found none.
#include <string>
#include <cstring>
#include <iostream>
#include <istream>
#include <ostream>
#include <fstream>
#include <iomanip>
#include <filesystem>
using namespace std;
class path{
public:
string parent_directory;
string root_directory;
};
class Data{
public:
string userName;
string nickName;
string fName;
string arena_FName;
string lName;
string arena_LName;
string email;
string arenaEmail;
friend std::istream& operator>>(std::istream& input, Data& d);
};
std::istream& operator>>(std::istream& input, Data& d){
std::getline(input, d.userName);
std::getline(input, d.nickName);
//...
std::getline(input, d.arenaEmail);
return input;
}
int main(){
ifstream myfile("myfunk.txt", ios::in);
ofstream arena("arena.txt");
myfile.open("myfunk.txt", ios::in);
if(myfile){
cout << "Input file open." << endl;
}
arena.open("arena.txt", ios::out | ios::app);
if(arena){
cout << "Output file open." << endl;
}
cout << "file opening test: success" << endl;
int x = 0;
int y = 4101; //Total number of users in the directory.
int z = 0; //For inputting the required lines of info for each profile.
int profile = 0;
bool valid = false;
string role;
//string arenaRole;
bool post = false;
string line;
string p = "This PC/..."; //Path to the folder of the individual pictures.
//myVar.save("...");
string p = "...";
path path1;
path root_directory;
path parent_directory;
//bool is_directory(const std::filesystem::path& p, std::error_code& ec) noexcept; //Checks if current location is a directory.
//bool postPic;
const unsigned int MAXIMUM_DATA = 4100u;
Data database[MAXIMUM_DATA];
cout << "All variables but the filesystem have been accepted! Please install this program on the network." << endl;
while(x < y){
cout << "Primary loop functioning" << endl;
if(post = true){
getline(myfile, line); //Grab and read next line.
myfile >> line;
line = userName[x];
arena << "Username: " << userName[x] << "\n";
z++;
getline(myfile, line);
myfile >> line;
line = role[x];
arena << "Role: " << role[x] << "\n";
z++;
getline(myfile, line);
line = nickName[x];
myfile >> nickName[x];
arena << "nickname: " << nickName[x] << "\n";
z++;
getline(myfile, line);
line = fName[x];
myfile >> fName;
arena << "First Name: " << fName[x] << "\n";
z++;
getline(myfile, line);
line = lName[x];
myfile >> lName;
arena << "Last Name: " << lName[x] << "\n";
z++;
getline(myfile, line);
myfile >> line;
line = email[x];
arena << "Email: " << email[x] << "\n";
getline(myfile, line);
z = 0; //Next profile...
}
int data;
while(myfile >> data){
if(nickName[x] = NULL){
myfile >> "<Error> Some required information is missing! Contact user! </Error> /n";
valid = false;
post = false;
x++;
}
if(email[x] != NULL){
std::string str("#");
std::string str2(".com");
std::string str3(".net");
std::string str4(".edu");
if(std::size_t found = email[x].find(str) & (std::size_t found = email[x].find(str2) || std::size_t found = email[x].find(str3) || std::size_t found = email[x].find(str4)){
valid = true;
if(valid = true){
post = true;
}
}
else{
valid = false;
post = false;
x++;
}
}
}
}
}
}
x++;
}
//x++;
myfile.close(); //Closes the file in the directory.
arena.close(); //Closes the file in Arena.
return 0;
}
Let's rework your code.
First, let's create a data structure for the data:
class Data
{
public:
string userName;
string nickName;
string fName;
string arena_FName;
string lName;
string arena_LName;
string email;
string arenaEmail;
};
If you need an array for the data, it would be declared as:
const unsigned int MAXIMUM_DATA = 4100u;
Data database[MAXIMUM_DATA];
Next, let's overload the extraction operator>> to make reading easier:
class Data
{
public:
//...
friend std::istream& operator>>(std::istream& input, Data& d);
};
std::istream& operator>>(std::istream& input, Data& d)
{
std::getline(input, d.userName);
std::getline(input, d.nickName);
//...
std::getline(input, d.arenaEmail);
return input;
}
This simplifies your input loop to:
std::vector<Data> database;
Data d;
while (my_file >> d)
{
database.push_back(d);
}
You can query the amount of data read in by using the std::vector::size() method, i.e. database.size().
Also, you don't need a separate structure for a file path. A simple std::string will suffice. I recommend using forward slash, '/', because it is recognized by both Windows and *nix operating systems and won't be interpreted as an escape character.

Getting an error here, not sure what it is though [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
my build is totally successful here, yet not outputting to my text file, I know I asked a question a few days ago about this program, and I've since changed it. What am I doing wrong now?
Thanks in advance guys.
I'm trying to input from an employeesIn.txt file and create an employeesOut.txt file made of employee structures.
Here's my text file.
123,John,Brown,125 Prarie Street,Staunton,IL,62088
124,Matt,Larson,126 Hudson Road,Edwardsville,IL,62025
125,Joe,Baratta,1542 Elizabeth Road,Highland,IL,62088
126,Kristin,Killebrew,123 Prewitt Drive,Alton,IL,62026
127,Tyrone,Meyer,street,999 Orchard Lane,Livingston,62088
The output should look like
Employee Record: 123
Name: John Brown
Home Address: 125 Prarie Street
Staunton, IL 62088
Employee Record: 124
Name Matt Larson
Home Address:.... and so on
Here's my code.
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
struct Person {
string first;
string last;
};
struct Address {
string street;
string city;
string state;
string zipcode;
};
struct Employee {
Person name;
Address homeAddress;
int eid;
};
int readEmployee(istream& in, Employee eArray[]);
void displayEmployee(ostream& out,Employee eArray[], int EmployeePopulation);
const int arr=50;
Employee eArray[arr];
ifstream fin;
ofstream fout;
int main(int argc, const char * argv[])
{
fin.open("employeesIn.txt");
if (!fin.is_open()) {
cerr << "Error opening employeesIn.txt for reading." << endl;
exit(1);
}
fout.open("employeesOut.txt");
if (!fout.is_open()) {
cerr << "Error opening employeesOut.txt for writing." << endl;
exit(1);
}
int tingle = readEmployee(fin, eArray);
fin.close();
displayEmployee(fout, eArray, tingle);
fout.close();
exit(0);
}
int readEmployee(istream& in, Employee eArray[])
{
string eidText;
string line;
getline(in, line);
int EmployeePopulation = 0;
while (!in.eof()) {
getline(in, eidText, ',');
eArray[EmployeePopulation].eid = stoi(eidText);
getline(in, eArray[EmployeePopulation].name.first, ',');
getline(in, eArray[EmployeePopulation].name.last, ',');
getline(in, eArray[EmployeePopulation].homeAddress.street, ',');
getline(in, eArray[EmployeePopulation].homeAddress.city, ',');
getline(in, eArray[EmployeePopulation].homeAddress.state, ',');
getline(in, eArray[EmployeePopulation].homeAddress.zipcode);
EmployeePopulation++;
}
return EmployeePopulation;
}
void displayEmployee(ostream& out, Employee eArray[], int EmployeePopulation)
{
for (int i = 0; i <= EmployeePopulation - 1; i++) {
out << "Employee Record: " << eArray[i].eid
<< endl
<< "Name: " << eArray[i].name.first << " " << eArray[i].name.last
<< endl
<< "Home address: " << eArray[i].homeAddress.street
<< endl
<< eArray[i].homeAddress.city << ", " << eArray[i].homeAddress.state << " " << eArray[i].homeAddress.zipcode
<< endl
<< endl;
}
}
Two things:
You should use return 0 rather than exit(0) at the end of main.
Checking for eof after you have performed several reads and tried to convert the data is wrong. You need to check for failure of the reads themselves.
This corrects the eof issue. The program was crashing for me because stoi threw an exception when the read failed.
int readEmployee(istream& in, Employee eArray[])
{
string eidText;
string line;
//This discards the first line. Incorrect for the test data you supplied.
getline(in, line);
int EmployeePopulation = 0;
//Check for errors while reading, not eof after the fact.
//This was crashing because stoi failed when no data was
//read due to eof being true after the loop check.
while( getline(in, eidText, ',') &&
getline(in, eArray[EmployeePopulation].name.first, ',') &&
getline(in, eArray[EmployeePopulation].name.last, ',') &&
getline(in, eArray[EmployeePopulation].homeAddress.street, ',') &&
getline(in, eArray[EmployeePopulation].homeAddress.city, ',') &&
getline(in, eArray[EmployeePopulation].homeAddress.state, ',') &&
getline(in, eArray[EmployeePopulation].homeAddress.zipcode))
{
eArray[EmployeePopulation].eid = stoi(eidText);
EmployeePopulation++;
}
return EmployeePopulation;
}
You would have fewer problems if you used a vector of Employee.
You could pass it by reference to the functions.
The functions could get the number of employees by using std::vector::size().
The std::vector automatically expands when using the push_back method.
If you created input and output methods for your classes, you wouldn't have to violate encapsulation:
class Person // using class to support privacy and encapsulation
{
std::string first_name;
std::string last_name;
public:
friend std::istream& operator>>(std::istream& inp, Person& p);
friend std::ostream& operator<<(std::ostream& out, const Person& p);
};
std::istream& operator>>(std::istream& inp, Person& p)
{
std::getline(inp, p.first_name, ',');
std::getline(inp, p.last_name, ',');
}
std:ostream& operator<<(std::ostream& out, const Peron& p)
{
out << "Name: ";
out << p.first_name;
out << " ";
out << p.last_name;
}
class Employee
{
Person name;
Address addr;
public:
friend std::istream& operator>>(std::istream& inp, Employee& e);
};
std::istream& operator>>(std::istream& inp, Employee& e)
{
inp >> name;
inp >> addr;
};
The missing formatted input and output are left as an exercise for the reader.
In your readEmployee function, you passed isstream& in.I suppose you should be checking for while (!in.eof()) ans not while (!fin.eof()).
And your getline(fin, line); should be getline(in, line); too.

Program not writing to file like I thought it would

I thought I had this completely worked out, but it isn't actually writing anything to the file. It is opening the employeesOut.txt file but not writing anything. Any guesses? I'm getting the error
Here is the input file as requested.
123,John,Brown,125 Prarie Street,Staunton,IL,62088
124,Matt,Larson,126 Hudson Road,Edwardsville,IL,62025
125,Joe,Baratta,1542 Elizabeth Road,Highland,IL,62088
126,Kristin,Killebrew,123 Prewitt Drive,Alton,IL,62026
127,Tyrone,Meyer,street,999 Orchard Lane,Livingston,62088
libc++abi.dylib: terminating with uncaught exception of type std::invalid_argument: stoi: no conversion
(lldb)
I believe the error is within my main.cpp, so here that is.
#include <iostream>
#include <string>
#include <fstream>
#include "Employee.h"
using namespace std;
bool openFileForReading(ifstream& fin, const string& filename);
bool openFileForWriting(ofstream& fout, const string& filename);
int readFromFile(ifstream& in, Employee empArray[]);
void writeToFile(ofstream& out, const Employee empArray[], const int numberofEmployees);
int main(){
ifstream fin;
ofstream fout;
if(!openFileForReading(fin, "employeesIn.txt")) {
cerr << "Error opening employeesIn.txt for reading." << endl;
exit(1);
}
if(!openFileForWriting(fout, "employeesOut.txt")) {
cerr << "Error opeing employeesOut.txt for writing." << endl;
exit(1);
}
Employee employeeArray[50];
int employeeCount = readFromFile(fin, employeeArray);
fin.close();
writeToFile(fout, employeeArray, employeeCount);
fout.close();
cout << "Program successful." << endl << endl;
return 0;
}
bool openFileForReading(ifstream& fin, const string& filename) {
fin.open("employeesIn.txt");
return (fin.is_open());
}
bool openFileForWriting(ofstream& fout, const string& filename) {
fout.open("employeesOut.txt");
return (fout.is_open());
}
int readFromFile(ifstream& in, Employee empArray[]) {
int temp = 0;
string eidText;
string first;
string last;
string street;
string city;
string state;
string zipcode;
while(!in.eof()) {
getline(in, eidText, ',');
getline(in, first, ',');
getline(in, last, ',');
getline(in, street, ',');
getline(in, city, ',');
getline(in, state, ',');
getline(in, zipcode, ',');
empArray[temp].setEid(stoi(eidText));
empArray[temp].setName(first, last);
empArray[temp].setAddress(street, city, state, zipcode);
temp++;
}
return temp;
}
void writeToFile(ofstream& out, const Employee empArray[], const int numberOfEmployees) {
for (int i = 0; i < numberOfEmployees; i++){
out << "Employee Record: " << empArray[i].getEid()
<< endl
<< "Name: " << empArray[i].getName()
<< endl
<< "Home Address: " << empArray[i].getAddress()
<< endl
<< endl;
}
}
Your initial problem is solved by changing your getline(in, zipcode, ','); line to getline(in, zipcode, '\n');, since this will make getline end on the linebreak character. The error is generated when stoi is given 'Matt' as an argument.
However, your readFromFile function is receiving a copy of your array, and so the changes it makes aren't moved back into your main() function (since you're returning the count, not the array).
Since passing an array of references is messy, try instead using a std::vector (after #includeing <vector>) to group your individual employees. If Employee.H specifies a parameter-less constructor or no constructor (and you have a default constructor from your compiler), then
std::vector<Employee> employeeVector;
void readFromFile(ifstream& in, std::vector<Employee> &empVec);
void readFromFile(ifstream& in, std::vector<Employee> &empVec) {
// int temp = 0; unneeded.
string eidText;
...
string zipcode;
while(!in.eof()) {
getline(in, eidText, ',');
...
getline(in, zipcode, '\n');
Employee tempEmp();
tempEmp.setEid(stoi(eidText));
...
empVec.push_back(tempEmp);
// temp++; no longer need this
}
}
might be a better option. Even if the constructor is horribly complicated, it's still likely this would be simpler than arrays of references (you'd have to change the Employee tempEmp(); line though. Incidentally, if this complains and won't compile, I probably hit the MVP error - remove the ()s and you'll be fine.
Edit:
Since you've been instructed to use an array of Employees, you can choose to return the array, if you wish, or alternatively passing it by pointer should be legal. This would require that you iterate through by moving the pointer along the array in a similar manner to your original code. I've left the vector approach above, since I think it's cleaner, but since you can't use it, you can choose from the two alternatives (return array, pass pointer instead of object). My guess is you're supposed to opt for the pointer, since this now appears to be a homework-style problem.
In that case, you can use
int main() {
...
Employee* empPtr = employeeArray;
...
}
void readFromFile(ifstream& in, Employee* empPtr) {
string eidText;
...
string zipcode;
while(!in.eof()) {
getline(in, eidText, ',');
...
getline(in, zipcode, '\n');
(*empPtr).setEid(stoi(eidText));
...
empPtr++;
}
}

C++ reading from data from text file

I have the following data:
$GPVTG,,T,,M,0.00,N,0.0,K,A*13
I need to read the data, however there are blanks in between the commas, therefore I am not sure how I should read the data.
Also, how do I select GPVTG only for a group of data? For example:
GPVTG,,T,,M
GPGGA,184945.00
GPRMC,18494
GPVTG,,T,,M,0
GPGGA,184946.000,3409
I have tried using:
/* read data line */
fgets(gpsString,100,gpsHandle);
char type[10] = "GPVTG";
sscanf(gpsString," %GPVTG", &type);
if (strcmp(gpsString, "GPTVG") == 0){
printf("%s\n",gpsString);
}
Thats what i'd do
#include <iostream>
#include <vector>
#include <sstream>
#include <fstream>
#include <string>
using namespace std;
vector<string> &split(const string &s, char delim, vector<string> &elems) {
stringstream ss(s);
string item;
while (getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
vector<string> split(const string &s, char delim) {
vector<string> elems;
split(s, delim, elems);
return elems;
}
int main()
{
ifstream ifs("file.txt");
string data_string;
while ( getline( ifs, data_string ) )
{
//i think you'd want to erase first $ charachter
if ( !data_string.empty() ) data_string.erase( data_string.begin() );
//now all data put into array:
vector<string> data_array = split ( data_string, ',' );
if ( data_array[0] == "GPVTG" )
{
//do whatever you want with that data entry
cout << data_string;
}
}
return 0;
}
Should handle your task. All empty elements will be empty "" strings in array. Ask if you need anything else.
Credits for split functions belong to Split a string in C++? answer.
How about this
#include <istream>
#include <sstream>
class CSVInputStream {
public:
CSVInputStream(std::istream& ist) : input(ist) {}
std::istream& input;
};
CSVInputStream& operator>>(CSVInputStream& in, std::string& target) {
if (!in.input) return in;
std::getline(in.input, target , ',');
return in;
}
template <typename T>
CSVInputStream& operator>>(CSVInputStream& in, T& target) {
if (!in.input) return in;
std::string line;
std::getline(in.input, line , ',');
std::stringstream translator;
translator << line;
translator >> target;
return in;
}
//--------------------------------------------------------------------
// Usage follow, perhaps in another file
//--------------------------------------------------------------------
#include <fstream>
#include <iostream>
int main() {
std::ifstream file;
file.open("testcsv.csv");
CSVInputStream input(file);
std::string sentence_type;
double track_made_good;
char code;
double unused;
double speed_kph;
char speed_unit_kph;
double speed_kmh;
char speed_unit_kmh;
input >> sentence_type >> track_made_good >> code;
input >> unused >> unused;
input >> speed_kph >> speed_unit_kph;
input >> speed_kmh >> speed_unit_kmh;
std::cout << sentence_type << " - " << track_made_good << " - ";
std::cout << speed_kmh << " " << speed_unit_kmh << " - ";
std::cout << speed_kph << " " << speed_unit_kph << std::endl;;
}
This separates the comma separation from the reading of the values, and can be reused on
most other comma separated stuff.
If you want use C++ style code based on fstream:
fin.open(input);
cout << "readed";
string str;
getline(fin, str); // read one line per time