I'm trying to split this a string with a comma as a delimeter. I put a string "Smith,Erdos,William" and it just outputs "William" but not Smith and Erdos. There must be something wrong here that I just can't see, can anyone help?
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
int main() {
int numScenarios(0);
int numPapers(0);
int numWriters(0);
std::vector<std::string> paperTitles (1);
std::vector<std::string> paperAuthors (1);
std::vector<std::string> splitAuthors (1);
std::string token;
std::string input;
std::cin >> numScenarios;
std::cin >> numPapers >> numWriters;
for (int i(0); i < numPapers; ++i) {
std::getline(std::cin,input);
std::istringstream iss(input);
while(getline(iss,token,','));
{
std::cout << token << std::endl;
}
//paperTitles.push_back(input);
//input = '\0';
}
for (int i(0); i < numWriters; ++i) {
getline(std::cin,input);
paperAuthors.push_back(input);
input = '\0';
}
return 0;
}
while(getline(iss,token,',')); // <== look closely
Related
I have a string of different integers separated by a comma. For example "45,67,2,3,8,9,123,5,6,3,9,4,7,2,4,4,5,69,9,99". I want to read this line as a stringstream and put integers to the vector of integers. On the console, it displays "no response on stdout".
The code looks as follows:
#include <sstream>
#include <vector>
#include <iostream>
using namespace std;
vector<int> parseInts(string str) {
stringstream myString;
vector<int> of_integers;
char ch;
int a;
for(int k = 0; k<str.size(); k++)
{
myString >> a >> ch;
of_integers[k] = a;
}
return of_integers;
}
int main() {
string str;
cin >> str;
vector<int> integers = parseInts(str); //function parseInts
for(int i = 0; i < integers.size(); i++) {
cout << integers[i] << "\n";
}
return 0;
}
The working code:
#include <sstream>
#include <vector>
#include <iostream>
using namespace std;
vector<int> parseInts(string str) {
stringstream myString(str);
int size = str.size();
vector<int> of_integers;
char ch = ',';
int a=0;
while(myString.eof()!=1)
{
myString >> a >> ch;
of_integers.push_back(a);
}
return of_integers;
}
int main() {
string str;
cin >> str;
vector<int> integers;
integers = parseInts(str);
for (int i = 0; i < integers.size(); i++) {
cout << integers[i] << "\n";
}
return 0;
}
Thanks for #jpmarinier, for referencing an useful stringstream function .eof() that detects when the stringstream ended.
The code worked well.
Input:
45,67,2,3,8,9,123,5,6,3,9,4,7,2,4,4,5,69,9,99
Output:
45
67
2
3
8
9
123
5
6
3
9
4
7
2
4
4
5
69
9
99
while using stringstream, I came across a piece for Parsing a comma-delimited std::string as below; I find for loop operation unique and new contrary to conventional operation as for(statement 1;statement 2;statement 3), I would like to understand this for loop for (int i; ss >> i;) used in below code, please let me know about these different use, thanks a lot.
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
int main()
{
std::string str = "1,2,3,4,5,6";
std::vector<int> vect;
std::stringstream ss(str);
for (int i; ss >> i;) {
vect.push_back(i);
if (ss.peek() == ',')
ss.ignore();
}
for (std::size_t i = 0; i < vect.size(); i++)
std::cout << vect[i] << std::endl;
}
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
cin.ignore();
while(t--){
string s;
getline(cin,s);
int i =0;
int count =0;
while(i<s.size()){
if(s[i]!=' '){
//cout<<count<<":";
s[count++]=s[i];
}
i++;
}
s[count]='\0';
cout<<s<<endl;
}
return 0;
}
Why in the end String is not terminating with '\0'?
For Input:
2
geeks for geeks
g f g
your output is:
geeksforgeeksks
gfgg f g
To remove a character from a string, you should use erase.
See the remove-erase idiom.
std::string is not a C-style null terminated string (but you can obtain one from it). As such, inserting a null character will not terminate it. If you want to truncate a string from the end, you can simply resize() it. Otherwise, if you want to remove characters, you can erase() them.
You say you want to remove spaces. To do that with your existing code, simply replace s[count]='\0'; with s.resize(count);, eg:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
cin.ignore();
while (t--){
string s;
getline(cin, s);
int i = 0;
int count = 0;
while (i < s.size()){
if (s[i] != ' '){
//cout<<count<<":";
s[count++] = s[i];
}
i++;
}
s.resize(count);
cout << s << endl;
}
return 0;
}
However, a better way to handle this would look more like this:
#include <iostream>
#include <string>
int main()
{
int t;
std::cin >> t;
std::cin.ignore();
while (t--){
std::string s;
std::getline(cin, s);
std::string::size_type idx = 0;
while ((idx = s.find(‘ ‘, idx)) != std::string::npos){
s.erase(idx, 1);
}
std::cout << s << std::endl;
}
return 0;
}
Alternatively:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
int t;
std::cin >> t;
std::cin.ignore();
while (t--){
std::string s;
std::getline(cin, s);
std::string::iterator iter = std::remove(s.begin(), s.end(), ‘ ‘);
s.erase(iter, s.end());
std::cout << s << std::endl;
}
return 0;
}
Within this function, I am passing multiple files. It was implemented with arrays before, and now I need to convert all of the arrays to vectors. The issue I have is when I read in from the files, it does not stop. Why??
void readIn(ifstream &iFile, vector<string> &itemName, vector<double> &itemPrice, vector<double> &quantity)
{
int x = 0;
string str;
string nTemp;
double pTemp;
int qTemp;
while(!iFile.eof())
{
getline(iFile, nTemp);
iFile.ignore();
itemName.push_back(nTemp);
iFile >> pTemp;
itemPrice.push_back(pTemp);
iFile >> qTemp;
quantity.push_back(qTemp);
cout << itemName.size() << " " << itemPrice.size() << " " << quantity.size() << endl;
}
readIn(appIn, appName, appPrice, appquantity);
readIn(drinkIn, drinkName, drinkPrice, driquantity);
readIn(entreeIn, entreeName, entreePrice, entquantity);
readIn(dessertIn, desName, desPrice, dessquantity);
This is the function and calls. Not sure why when outputting the item name, item price and quantity sizes, it just continually reads in values.
Expanding your code to an executable example:
#include <vector>
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
void readIn(ifstream &iFile, vector<string> &itemName, vector<double> &itemPrice,
vector<double> &quantity)
{
int x = 0;
string str;
string nTemp;
double pTemp;
int qTemp;
while(!iFile.eof())
{
getline(iFile, nTemp);
iFile.ignore();
itemName.push_back(nTemp);
iFile >> pTemp;
itemPrice.push_back(pTemp);
iFile >> qTemp;
quantity.push_back(qTemp);
cout << itemName.size() << " " << itemPrice.size() << " " << quantity.size()
<< endl;
}
}
int main () {
vector<string> nam;
vector<double> price,quantity;
ifstream in;
in.open("data_adamp.txt");
readIn(in,nam,price,quantity);
}
Given ...
$ cat data_adamp.txt
animal a 1 2
beach b 3 4
cart c 4 5
dog d 6 7
... compiling with (GCC version 6.4.0):
$ gcc adamp.cpp -lstdc++ -oadamp
... lets me run:
$ ./adamp
... which does indeed never stop.
One way to solve this problem is to tokenize each line and convert the two rightmost fields to doubles and the rest to the record name, e.g. (using the approach in the highest-ranked answer to How do I iterate over the words of a string?):
#include <vector>
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <iterator>
using namespace std;
// See the highest-scoring answer to https://stackoverflow.com/questions/236129/how-do-i-iterate-over-the-words-of-a-string/236803#236803
template<typename Out>
void split(const std::string &s, char delim, Out result) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
*(result++) = item;
}
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, std::back_inserter(elems));
return elems;
}
void readIn(ifstream &iFile, vector<string> &itemName, vector<double> &itemPrice,
vector<double> &quantity)
{
string nTemp;
double pTemp;
int qTemp;
string line;
while(getline(iFile,line))
{
char delim = ' ';
vector<string> s = split(line,delim);
istringstream ss;
ss.str(s.back());
ss >> qTemp;
s.pop_back();
ss.str(s.back());
ss.clear();
ss >> pTemp;
s.pop_back();
nTemp = "";
for (int i = 0; i < s.size(); i++)
{
if (i > 0) nTemp.append(" ");
nTemp.append(s[i]);
}
itemName.push_back(nTemp);
itemPrice.push_back(pTemp);
quantity.push_back(qTemp);
cout << nTemp << "++" << pTemp << "++" << qTemp << endl;
}
}
int main () {
vector<string> nam;
vector<double> price,quantity;
ifstream in;
in.open("data_adamp.txt");
readIn(in,nam,price,quantity);
}
How would I get a list of numbers from the user and then tokenize them.
This is what I have but it doesn't get anything except for the first number:
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
int main()
{
string line = "";
cin >> line;
stringstream lineStream(line);
int i;
vector<int> values;
while (lineStream >> i)
values.push_back(i);
for(int i=0; i<values.size(); i++)
cout << values[i] << endl;
system("PAUSE");
return 0;
}
Related Posts:
C++, Going from string to stringstream to vector
Int Tokenizer
Here is probably the easiest way to read values from cin into a container:
#include <iostream>
#include <iterator>
#include <vector>
int main()
{
std::vector<int> values;
std::copy(
std::istream_iterator<int>(std::cin),
std::istream_iterator<int>(),
std::back_inserter(values));
// For symmetry with the question copy back to std::cout
std::copy(
values.begin(),
values.end(),
std::ostream_iterator<int>(std::cout,"\n"));
}
I believe cin >> breaks on whitespace, which means you're only getting the first number entered.
try:
getline(cin, line);
Like Donnie mentioned cin breaks on whitespace, so do overcome this we can use a 'getline()', the following example works nicely:
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
int main()
{
string line = "";
::getline(std::cin,line,'\n');
std::stringstream lineStream(line);
int i;
std::vector<int> values;
while (lineStream >> i)
values.push_back(i);
for(int i=0; i<values.size(); i++)
cout << values[i] << endl;
system("PAUSE");
return 0;
}
on top of main
string line = "";
getline (cin, line );
stringstream lineStream(line);
Yep, and is the string version of getline, no the istream one.
OK: Pavel Minaev has the best answer.
But all the people mentioning that cin breaks on white space.
That is a good thing (because it also ignores white space);
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
int main()
{
int i;
vector<int> values;
// prefer to use std::copy() but this works.
while (std::cin >> i)
{
values.push_back(i);
}
// prefer to use std::copy but this works.
for(vector<int>::const_iterator loop = values.begin();loop != values.end();++loop)
{
cout << *loop << endl;
}
return 0;
}