C++ getline() jumped over empty strings - c++

I'm reading with my c++ program csv file:
abc;def;ghi
10;;10
by this code:
while(getline(in, str, '\n')){
stringstream ss;
while(getline(ss, str, ';')){
line.add(str);
}
}
Where in is input file, str is string variable and line is my collection (like vector). But getline jumped over the empty string in csv file.
Can anyone help me to reading empty string, too?
Thanks :)

You've never initialized your stream!
Try this:
#include <string> // for std::string and std::getline
#include <sstream> // for std::istringstream
for (std::string jimbob; std::getline(in, jimbob); )
{
std::istringstream marysue(jimbob); // !
for (std::string charlie; std::getline(marysue, charlie, ';'); )
{
line.add(charlie);
}
}

Related

Reading all the words in a text file in C++

I have a large .txt file and I want to read all of the words inside it and print them on the screen. The first thing I did was to use std::getline() in this way:
std::vector<std::string> words;
std::string line;
while(std::getline(std::cin,line)){
words.push_back(line);
}
and then I printed out all the words present in the vector words. The .txt file is passed from command line as ./a.out < myTxt.txt.
The problem is that each component of the vector is a whole line, and so I am not reading each word.
The problem, I guess, is the spaces between words: how can I tell the code to ignore them? More specifically, is there any function that I can use in order to read each word from a .txt file?
UPDATE:
I'm trying to avoid all the commas ., but also ? ! (). I used find_first_of(), but my program doesn't work. Also, I don't know how to set what are the characters I don't want to be read, i.e. ., ?, !, and so on
std::vector<std::string> my_vec;
std::string line;
while(std::cin>>line){
std::size_t pos = line.find_first_of("!");
std::string line = line.substr(pos);
my_vec.push_back(line);
}
'>>' operator of type string exactly fills your requirements.
std::vector<std::string> words;
std::string line;
while (std::cin >> line) {
words.push_back(line);
}
If you need remove some noisy characters, e.g. ',','.', you can replace them with space character first.
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
int main() {
std::vector<std::string> words;
std::string line;
while (getline(std::cin, line)) {
std::transform(line.begin(), line.end(), line.begin(),
[](char c) { return std::isalnum(c) ? c : ' '; });
std::stringstream linestream(line);
std::string w;
while (linestream >> w) {
std::cout << w << "\n";
words.push_back(w);
}
}
}
cppreference
The getline function, as it sounds, only returns a whole line. You can split each line on spaces after reading it, or you can read word by word using operator>>:
string word;
while (cin >> word){
cout << word << "\n";
words.push_back(word);
}
Use operator>> instead of std::getline(). The operator will read individual whitespace-separated substrings for you.
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> my_vec;
std::string s;
while (std::cin >> s){
// use s as needed...
}
However, you may still end up receiving strings that have punctuation in them without any surrounding whitespace, ie hello,world, so you will have to manually split those strings as needed, eg:
#include <iostream>
#include <string>
#include <vector>
#include <cctype>
std::vector<std::string> my_vec;
std::string s;
while (std::cin >> s){
std::string::size_type start = 0, pos;
while ((pos = s.find_first_of(".,?!()", start)) != std::string::npos){
my_vec.push_back(s.substr(start, pos-start));
start = s.find_first_not_of(".,?!() \t\f\r\n\v", pos+1);
}
if (start == 0)
my_vec.push_back(s);
else if (start != std::string::npos)
my_vec.push_back(s.substr(start));
}

Using getline to divide input, using commas as delim

I have a text file with movie info, separated by commas. I will provide a line for insight:
8,The Good the Bad and the Ugly,1966,2
I need to take this line, and divide the different pieces by their comma to fit the format of this function:
void addMovieNode(int ranking, std::string title, int releaseYear, int quantity);
The text file's information is in order with the function but I am unclear on how the getline operation operates.
I know I can pass in the text file like
getline("moveInfo.txt", string, ",");
but how will that translate in terms of what is actually going on with the output?
I read the manual on the cplusplus website but that did not help to clarify very much.
You can use a string and stringstream:
#include <sstream>
#include <string>
#include <fstream>
ifstream infile( "moveInfo.txt" );
while (infile)
{
std::string line;
if (!std::getline( infile, line,',' )) break;
std::istringstream iss(line);
int ranking, releaseYear, quantity;
std::string title;
if (!(iss >> ranking >> title >> releaseYear >> quantity)) { break; }
}

How can I std::getline() a string?

Let say I have this string
string myString = "This is a test string:value1/value2/value3/"
How can I do something like this:
getline (myString, temp, '/');
I was thinking about output << myString to a file, and then using
getline (output, temp, '/') as usual, but I think there should be other ways.
Thanks, please help me.
getline extracts from a stream; so you want to put your string into a string-stream:
#include <sstream>
std::stringstream ss(myString);
getline(ss, temp, '/');

No matching function for call to 'get line' while exploding

No matching function for call to 'getline' when using this code:
ifstream myfile;
string line;
string line2;
myfile.open("example.txt");
while (! myfile.eof() )
{
getline (myfile, line);
getline (line, line2, '|');
cout<<line2;
}
In the example.txt i have info like this:
1|Name1|21|170
2|Name2|34|168
etc...
I really want to get the line till the | char...
I try few explode functions but they are only in string type but i need:
1st to be int
2nd to be char
3rd and 4th to be float.
It's really complicated that i want to do, and i can't explain it well. I hope someone will understand me.
getline receives as first argument an instance of the template basic_istream. string doesn't meet that requirement.
You could use stringstream:
#include <sstream>
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
string line;
string line2;
ifstream myfile("test/test.txt");
while (getline(myfile, line))
{
stringstream sline(line);
while (getline(sline, line2, '|'))
cout << line2 << endl;
}
return 0;
}

is it possible to read from a specific character in a line from a file in c++?

Hey all so I have to get values from a text file, but the values don't stand alone they are all written as this:
Population size: 30
Is there any way in c++ that I can read from after the ':'?
I've tried using the >> operator like:
string pop;
inFile >> pop;
but off course the whitespace terminates the statement before it gets to the number and for some reason using
inFile.getline(pop, 20);
gives me loads of errors because it does not want to write directly to string for some reason..
I don't really want to use a char array because then it won't be as easy to test for the number and extract that alone from the string.
So is there anyway I can use the getline function with a string?
And is it possible to read from after the ':' character?
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <cstdlib>
using namespace std;
int main()
{
string fname;
cin >> fname;
ifstream inFile;
inFile.open(fname.c_str());
string pop1;
getline(inFile,pop1);
cout << pop1;
return 0;
}
ok so here is my code with the new getline, but it still outputs nothing. it does correctly open the text file and it works with a char array
You are probably best to read the whole line then manipulate the string :-
std::string line;
std::getline(inFile, line);
line = line.substr(19); // Get character 20 onwards...
You are probably better too looking for the colon :-
size_t pos = line.find(":");
if (pos != string::npos)
{
line = line.substr(pos + 1);
}
Or something similar
Once you've done that you might want to feed it back into a stringstream so you can read ints and stuff?
int population;
std::istringstream ss(line);
ss >> population;
Obviously this all depends on what you want to do with the data
Assuming your data is in the form
<Key>:<Value>
One per line. Then I would do this:
std::string line;
while(std::getline(inFile, line))
{
std::stringstream linestream(line);
std::string key;
int value;
if (std::getline(linestream, key, ':') >> value)
{
// Got a key/value pair
}
}