C++ ifstream, issue loading with ";" - c++

int a, b;
while (infile >> a >> b)
{
// process pair (a,b)
}
So this is the code i've been watching but i ran into a problem because my strings doesn't have whitespaces between them, they have ";"
My code:
void load(string filename){ // [LOAD]
string line;
ifstream myfile(filename);
string thename;
string thenumber;
if (myfile.is_open())
{
while (myfile >> thename >> thenumber)
{
cout << thename << thenumber << endl;
//map_name.insert(make_pair(thename,thenumber));
}
myfile.close();
}
else cout << "Unable to open file";
}
[Inside the txt.file]
123;peter
789;oskar
456;jon
What i get right now is "thename" as 123;peter and "thenumber" as 789;oskar.
I want "thename" as peter and "thenumber" as 123 so i can then insert it back into my map correctly, How?

The infile >> a read from infile the eligible type for a. In your case a is int so '>>' expect to find an int. In your code myfile >> thename >> thenumber both are string type so they expect string type in your file. The problem is that string include ';' so the variable name will take all the row until it find \n(new line).
in your code
std::string thename, thenumber;
char delimeter(';'); //It is always '-' is it?
std::getline(std::cin, thename, delimeter);
std::getline(std::cin, thenumber);
also thenumber will be string type. To convert your thenumber into int:
std::istringstream ss(thenumber);
int i;
ss >> i;
if (ss.fail())
{
// Error
}
else
{
std::cout << "The integer value is: " << i;
}
return 0;

It is fairly simple to read in a file in the format. You can use std::getline with a different delimiter to tell it where to stop reading the input.
while(getline(myfile, thenumber, ';')) // reads until ';' or end of file
{
getline(myfile, thename); // reads until newline or end of file
map_name.insert(make_pair(thename,thenumber));
}

You have to input a single string and then split it to get the name and number
....
#include <string>
#include <sstream>
#include <vector>
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
....
void load(string filename){
..........
if (myfile.is_open())
{
while (myfile >>whole)
{
std::vector<std::string> parts = split(whole, ';');
name = parts[0];
number = parts[1];
}
}

Related

getline() skipping over string line from text file

My project is supposed to basically sum up the value of all ints on a line and print the word in the next line that amount of times. However, something is causing it to skip over the string line where the word but I am getting the summed value right.
Input file:
1,2,3
word
2,3,4
word2
Here is my code:
int main() {
std::ifstream in;
std::ofstream out;
std::string line;
in.open("input.txt");
out.open("output.txt");
while(std::getline(in, line)){
std::stringstream ss(line);
while(ss){
std::string word;
std::string number;
int a = 0;
while(std::getline(ss, number, ',')){
a = a + atoi(number.c_str());}
std::getline(ss, word);
for (int z = 0; z < a; z++){
out << word << ",";}
out << "\n";
}
}
return(0);
}
Output I'm getting:
,,,,,,
,,,,,,,,,
What I should be getting:
word,word,word,word,word,word
word2,word2,word2,word2,word2,word2,word2,word2
Change:
std::getline(ss, word);
To this:
// Gets the next line in input.txt and stores it in the variable 'word'
std::getline(in, word);
This is because during the while loop, ss is emptied (exhausted) by the nested while loop (the 2nd while loop) and has no words when it's contents are inserted into the variable 'word'.
Final code:
#include <iostream>
#include <fstream>
#include <sstream>
int main() {
std::ifstream in;
std::ofstream out;
std::string line;
in.open("input.txt");
out.open("output.txt");
while (std::getline(in, line)) {
std::stringstream ss(line);
while (ss) {
std::string word;
std::string number;
int a = 0;
while (std::getline(ss, number, ',')) {
a = a + atoi(number.c_str());
}
std::getline(in, word); // Changed line
for (int z = 0; z < a; z++) {
out << word << ",";
}
out << "\n";
}
}
return(0);
}

Convert string from getline into a number

I am trying to create a 2D array with vectors. I have a file that has for each line a set of numbers. So what I did I implemented a split function that every time I have a new number (separated by \t) it splits that and add it to the vector
vector<double> &split(const string &s, char delim, vector<double> &elems) {
stringstream ss(s);
string item;
while (getline(ss, item, delim)) {
cout << item << endl;
double number = atof(item.c_str());
cout << number;
elems.push_back(number);
}
return elems;
}
vector<double> split(const string &s, char delim) {
vector<double> elems;
split(s, delim, elems);
return elems;
}
After that I simply iterate through it.
int main()
{
ifstream file("./data/file.txt");
string row;
vector< vector<double> > matrix;
int line_count = -1;
while (getline(file, row)) {
line_count++;
if (line_count <= 4) continue;
vector<double> cols = split(row, '\t');
matrix.push_back(cols);
}
...
}
Now my issues is in this bit here:
while (getline(ss, item, delim)) {
cout << item << endl;
double number = atof(item.c_str());
cout << number;
Where item.c_str() is converted to a 0. Shouldn't that be still a string having the same value as item? It works on a separate example if I do straight from string to c_string, but when I use this getline I end up in this error situation,
hints?
instead of using atof use the stringstream
while(!ss.eof())
{
double number;
ss>>number;
}
EDIT:
I have updated your split function and removed the superfluous return.
void split(const string &s, vector<double> &elems) {
stringstream ss(s);
while (!ss.eof()) {
double number;
ss >> number;
cout << number;
elems.push_back(number);
}
}
int main()
{
std::vector<double> columns;
split("1.32\t1.65\t1.98456\t2.34",columns);
return 0;
}

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

Trouble with reading/outputting files

I want to open a file for reading then output what is in that .txt file, any suggestion on my code?
string process_word(ifstream &word){
string line, empty_str = "";
while (!word.eof()){
getline(word, line);
empty_str += line;
}
return empty_str;
}
int main(){
string scrambled_msg = "", input, output, line, word, line1, cnt;
cout << "input file: ";
cin >> input;
ifstream inFile(input);
cout << process_word(inFile);
}
Instead of:
while (!word.eof()) {
getline(word, line);
empty_str += line;
}
do:
while ( std::getline(word, line) ) {
empty_str += line;
}
and it would be also wise to give your variables more appropriate names.
Your function can be simplified to:
#include <iterator>
std::string process_word(std::ifstream& word)
{
return std::string{std::istream_iterator<char>{word},
std::istream_iterator<char>{}};
}
int main()
{
string input;
std::cin >> input;
std::ifstream inFile(input);
std::cout << process_word(inFile);
}

C++: File I/O having difficulty with opening and working with it

I'm having difficulty opening files and processing what is inside of them. What i want to do is
pull a line from the input file
init an istreamstream with the line
pull each word from the istringstream
i. process the word
do my specific function i've created
ii. write it to the output file
I'm not sure how to go about doing 1-3 can anyone help with my functions? This is what i have so far...
string process_word(ifstream &inFile){
string line, empty_str = "";
while (getline(inFile,line)){
empty_str += line;
}
return empty_str;
}
int main(){
string scrambled_msg = "", input, output, line, word, line1, cnt;
cout << "input file: ";
cin >> input;
cout << "output file: ";
cin >> output;
ifstream inFile(input);
ofstream outFile(output);
cout << process_word(inFile);
}
std::vector<std::string> process_word(std::ifstream& in)
{
std::string line;
std::vector<std::string> words;
while (std::getline(in, line)) // 1
{
std::istringstream iss{line}; // 2
std::move(std::istream_iterator<std::string>{in},
std::istream_iterator<std::string>{},
std::back_inserter(words));
}
return words;
}
int main()
{
std::ifstream in(file);
std::ofstream out(file);
auto words = process_word(in);
for (auto word : words)
// 3 i.
std::move(words.begin(), words.end(), // 3 ii.
std::ostream_iterator<std::string>{out});
}