I am trying to make a C++ program that receives user input, and extracts the individual words in the string, e.g. "Hello to Bob" would get "Hello", "to", "Bob". Eventually, I will be pushing these into a string vector. This is the format I tried to use when designing the code:
//string libraries and all other appropriate libraries have been included above here
string UserInput;
getline(cin,UserInput)
vector<string> words;
string temp=UserInput;
string pushBackVar;//this will eventually be used to pushback words into a vector
for (int i=0;i<UserInput.length();i++)
{
if(UserInput[i]==32)
{
pushBackVar=temp.erase(i,UserInput.length()-i);
//something like words.pushback(pushBackVar) will go here;
}
}
However, this only works for the first space encountered in the string.It does not work if there are any spaces before the word (e.g. if we have "Hello my World", pushBackVar will be "Hello" after the first loop, and then "Hello my" after the second loop, when I want "Hello" and "my".) How do I fix this? Is there any other better way to extract individual words from a string? I hope I haven't confused anyone.
See Split a string in C++?
#include <string>
#include <sstream>
#include <vector>
using namespace std;
void split(const string &s, char delim, vector<string> &elems) {
stringstream ss(s);
string item;
while (getline(ss, item, delim)) {
elems.push_back(item);
}
}
vector<string> split(const string &s, char delim) {
vector<string> elems;
split(s, delim, elems);
return elems;
}
So in your case just do:
words = split(temp,' ');
You can use the operator >> direct to a microbuffer (string) to extract the word. (getline is not needed). Take a look at the function below:
vector<string> Extract(const string& Text) {
vector<string> Words;
stringstream ss(Text);
string Buf;
while (ss >> Buf)
Words.push_back(Buf);
return Words;
}
#include <algorithm> // std::(copy)
#include <iostream> // std::(cin, cout)
#include <iterator> // std::(istream_iterator, back_inserter)
#include <sstream> // std::(istringstream)
#include <string> // std::(string)
#include <vector> // std::(vector)
using namespace std;
auto main()
-> int
{
string user_input;
getline( cin, user_input );
vector<string> words;
{
istringstream input_as_stream( user_input );
copy(
istream_iterator<string>( input_as_stream ),
istream_iterator<string>(),
back_inserter( words )
);
}
for( string const& word : words )
{
cout << word << '\n';
}
}
Here I have created a vector of words from the sentence.
#include<bits/stdc++.h>
using namespace std;
int main(){
string s = "the devil in the s";
string word;
vector<string> v;
for(int i=0; i<s.length(); i++){
if(s[i]!=' '){
word+=s[i];
}
else{
v.push_back(word);
if(i<s.length()+1)
word.clear();
}
}
v.push_back(word);
for(auto i:v){
cout<<i<<endl;
}
}
Related
I am having trouble splitting words of a string into a vector. I am trying to keep track of each word with a first and last integer. I believe my main issue has to do with how I am iterating over the string.
What would be ways to improve this function?
Input: "hello there how are you"
Actual Output: "hello", "there", "how", "are"
Expected Output: "hello", "there", "how", "are", "you"
std::vector <std::string> wordChopper(std::string& s)
{
std::vector<std::string> words;
int first = 0;
int last;
std::string word;
for(unsigned int i = 0; i < s.size(); i++)
{
if(s[i] != ' ')
{
last++;
}
else
{
word = s.substr(first,last);
words.push_back(word);
first = i+1;
last = 0;
}
}
return words;
}
I suggest:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <iterator>
using namespace std;
vector<string> wordChopper(const string & s)
{
istringstream iss(s);
return vector<string>(istream_iterator<string>{iss}, istream_iterator<string>());
}
int main()
{
for (auto & iter : wordChopper("hello there how are you"))
{
cout << iter << endl;
}
return 0;
}
I have given the widely used method in the comment. However, if you want to write your own function, I would suggest trying out something on the lines of:
std::vector<std::string> stringTokeniser(std::string originalString, char delimiter = ' ') {
std::vector<std::string> tokensVector;
std::string word;
for (const auto character : originalString) {
if (character != delimiter) {
word.push_back(character);
}
else {
tokensVector.push_back(word);
word.clear();
}
}
tokensVector.push_back(word);
return tokensVector;
}
I am having trouble splitting words of a string into a vector
There is no need for indexing, start and first positions, etc. if the words are separated by spaces.
Usage of std::stringstream accomplishes this:
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
std::vector <std::string> wordChopper(std::string s)
{
std::vector<std::string> words;
std::stringstream strm(s);
std::string word;
while (strm >> word)
words.push_back(word);
return words;
}
int main()
{
auto v = wordChopper("hello there how are you");
for (auto s : v)
std::cout << s << "\n";
}
Output:
hello
there
how
are
you
I'm working on a program where the user will input in the format x,0,0 and it will be saved to a file then read into an array where I can compare the values however I'm stuck when trying to read into a 2D array can someone please help? Think the error is in the struct part
This is what I have so far:
#include <iostream>
#include <string>
#include <fstream>
#include <cstring>
#include <sstream>
using namespace std;
struct listArray
{
string name[];
int price1[];
int price2[];
};
int main()
{
listArray la;
string line;
cout << "Enter your list: ";
ofstream fout;
fout.open("list.txt");
while (fout) {
getline(cin, line);
if (line == "-1")
break;
fout << line << endl;
}
fout.close();
int count = 0;
ifstream listFile;
listFile.open("list.txt");
if(listFile.is_open()){
while (listFile) {
getline(listFile, la.name[count], ",");
count++;
listFile.close();
}
}
You can use delimiter to grab the substring, and use this substring to fill your struct, an exemple of split:
#include<iostream>
std::vector<std::string> split(const string& input, const string& regex)
{
// passing -1 as the submatch index parameter performs splitting
std::regex re(regex);
std::sregex_token_iterator first{input.begin(), input.end(), re, -1},last;
return {first, last};
}
if you are using C++11 or higher, you can use std::vector for arrays, and you also can use boost library, they have nice support for delimiter and other stuffs.
#include<bits/stdc++.h>
using namespace std;
int main()
{
int i=0;
char a[100][100];
do {
cin>>a[i];
i++;
}while( strcmp(a[i],"\n") !=0 );
for(int j=0;j<i;i++)
{
cout<<a[i]<<endl;
}
return 0;
}
Here , i want to exit the do while loop as the users hits enter .But, the code doesn't come out of the loop..
The following reads one line and splits it on white-space. This code is not something one would normally expect a beginner to write from scratch. However, searching on Duckduckgo or Stackoverflow will reveal lots of variations on this theme. When progamming, know that you are probably not the first to need the functionality you seek. The engineering way is to find the best and learn from it. Study the code below. From one tiny example, you will learn about getline, string-streams, iterators, copy, back_inserter, and more. What a bargain!
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <vector>
int main() {
using namespace std;
vector<string> tokens;
{
string line;
getline(cin, line);
istringstream stream(line);
copy(istream_iterator<string>(stream),
istream_iterator<string>(),
back_inserter(tokens));
}
for (auto s : tokens) {
cout << s << '\n';
}
return 0;
}
First of all, we need to read the line until the '\n' character, which we can do with getline(). The extraction operator >> won't work here, since it will also stop reading input upon reaching a space. Once we get the whole line, we can put it into a stringstream and use cin >> str or getline(cin, str, ' ') to read the individual strings.
Another approach might be to take advantage of the fact that the extraction operator will leave the delimiter in the stream. We can then check if it's a '\n' with cin.peek().
Here's the code for the first approach:
#include <iostream> //include the standard library files individually
#include <vector> //#include <bits/stdc++.h> is terrible practice.
#include <sstream>
int main()
{
std::vector<std::string> words; //vector to store the strings
std::string line;
std::getline(std::cin, line); //get the whole line
std::stringstream ss(line); //create stringstream containing the line
std::string str;
while(std::getline(ss, str, ' ')) //loops until the input fails (when ss is empty)
{
words.push_back(str);
}
for(std::string &s : words)
{
std::cout << s << '\n';
}
}
And for the second approach:
#include <iostream> //include the standard library files individually
#include <vector> //#include <bits/stdc++.h> is terrible practice.
int main()
{
std::vector<std::string> words; //vector to store the strings
while(std::cin.peek() != '\n') //loop until next character to be read is '\n'
{
std::string str; //read a word
std::cin >> str;
words.push_back(str);
}
for(std::string &s : words)
{
std::cout << s << '\n';
}
}
You canuse getline to read ENTER, run on windows:
//#include<bits/stdc++.h>
#include <iostream>
#include <string> // for getline()
using namespace std;
int main()
{
int i = 0;
char a[100][100];
string temp;
do {
getline(std::cin, temp);
if (temp.empty())
break;
strcpy_s(a[i], temp.substr(0, 100).c_str());
} while (++i < 100);
for (int j = 0; j<i; j++)
{
cout << a[j] << endl;
}
return 0;
}
While each getline will got a whole line, like "hello world" will be read once, you can split it, just see this post.
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
vector<string> split_string(string s)
{
string buf;
stringstream ss(s);
vector<string> tokens;
while (ss >> buf)
tokens.push_back(buf);
return tokens;
}
int main()
{
cout << split_string("Alpha Beta Gamma");
}
when i try to split a string into a vector by using whitespaces i am not able to print out my solution.
i doesnt let me use std::cout but in my function the return value is given
why cant i use it like that? how do i fix this?
std::cout cannot take a vector, you need to iterate through the container and print each element separately, try using something like this:
int main()
{
string originalString = "Alpha Beta Gamma";
for (const auto& str : split_string(originalString))
cout << str << '\n';
return 0;
}
So say if I have this line in a text file.
AarI/CACCTGCNNNN'NNNN/'NNNNNNNNGCAGGTG//
What I want is to read this line into a string until the forwardslash appears and then start reading the next set of characters into another string.. So in this example I would have 3 strings containing
string1 = "AarI"
string2 = "CACCTGCNNNN'NNNN"
string3 = "'NNNNNNNNGCAGGTG"
Any idea how to go about this?
istream::getline() with a delim character of '/' - see: http://www.cplusplus.com/reference/istream/istream/getline/
Not the best or safest, probably amongst the simpler approaches.
Use sstream. The code below shows an example of how to split a string.
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
vector<string> split(string str, char delimiter);
int main(int argc, char **argv) {
string DNAstr = "AarI/CACCTGCNNNN'NNNN/'NNNNNNNNGCAGGTG//";
vector<string> splittedlines = split(DNAstr, '/');
for(int i = 0; i < splittedlines.size(); ++i)
cout <<""<<splittedlines[i] << " \n";
return 0;
}
vector<string> split(string str, char delimiter) {
vector<string> buffer;
stringstream ss(str);
string tok;
while(getline(ss, tok, delimiter)) {
buffer.push_back(tok);
}
return buffer;
}