Why am I getting incomplete reversed string - c++

For the string input like this - "i.like.this.program.very.much", the output should be "much.very.program.this.like.i".
This is my code -
void func(string s,int n){
vector<string>v;
string temp="";
for(int j=0;j<n;j++){
if(s[j]!='.'){
temp+=s[j];
}
else{
v.push_back(temp);
temp="";
}
}
reverse(v.begin(),v.end());
for(int i=0;i<v.size();i++){
cout<<v[i]<<".";
}
cout<<"\n";
}
Here 'n' is the string length and 's' is the string. I'm getting output as - "very.program.this.like.i."

The else block only executes when a period is encountered. Since there is no period at the end of the string it never pushes back the final word.
void func(string s, int n) {
vector<string>v;
string temp = "";
for (int j = 0; j < n; j++) {
if (s[j] != '.') {
temp += s[j];
}
else {
v.push_back(temp);
temp = "";
}
}
// v.push_back(temp); This will push the last word / letters
reverse(v.begin(), v.end());
for (int i = 0; i < v.size(); i++) {
cout << v[i] << ".";
}
cout << "\n";
}

void func(string s,int n){
vector<string>v;
string temp="";
for(int j=0;j<n;j++){
if(s[j]!='.' || j==0){
temp+=s[j];
}
else{
v.push_back(temp);
temp="";
}
}
reverse(v.begin(),v.end());
for(int i=0;i<v.size();i++){
cout<<v[i]<<".";
}
cout<<"\n";
}
The statement in your code appends the character only when the current index character is a period.

For starters the first parameters should be a constant reference to an object of the type std::string.
void func( const string &s, int n);
But if the compiler supports the C++ 17 Standard then the first parameter is even better to make of the type std::string_view.
The second parameter is redundant.
The function should return the reversed string.
Instead of using a loop you could use a string stream.
In the loop the sub-string after the last symbol '.' is not appended to the vector.
Instead of the vector it would be better to use the container std::forward_list because you will not need to reverse its elements.
I can suggest the following function definition as it is shown in the demonstrative program below.
#include <iostream>
#include <string>
#include <forward_list>
#include <iterator>
#include <sstream>
std::string reverse( const std::string &s, char c = '.' )
{
std::istringstream is( s );
std::forward_list<std::string> list;
std::string word;
while ( getline( is, word, c ) ) list.push_front( word );
bool first = true;
std::string result;
result.reserve( s.size() );
for ( const auto &item : list )
{
if ( !first ) result += c;
else first = false;
result += item;
}
return result;
}
int main()
{
std::string s( "i.like.this.program.very.much" );
std::cout << reverse( s ) << '\n';
return 0;
}
The program output is
much.very.program.this.like.i

Related

String function optimisation?

I'm new to C++ and i just wrote a function to tell me if certain characters in a string repeat or not:
bool repeats(string s)
{
int len = s.size(), c = 0;
for(int i = 0; i < len; i++){
for(int k = 0; k < len; k++){
if(i != k && s[i] == s[k]){
c++;
}
}
}
return c;
}
...but i can't help but think it's a bit congested for what it's supposed to do. Is there any way i could write such a function in less lines?
Is there any way i could write such a function in less lines?
With std, you might do:
bool repeats(const std::string& s)
{
return std::/*unordered_*/set<char>{s.begin(), s.end()}.size() != s.size();
}
#include <algorithm>
bool repeats(std::string s){
for (auto c : s){
if(std::count(s.begin(), s.end(), c) - 1)
return true;
}
return false;
}
Assuming you are not looking for repeated substrings :
#include <iostream>
#include <string>
#include <set>
std::set<char> ignore_characters{ ' ', '\n' };
bool has_repeated_characters(const std::string& input)
{
// std::set<char> is a collection of unique characters
std::set<char> seen_characters{};
// loop over all characters in the input string
for (const auto& c : input)
{
// skip characters to ignore, like spaces
if (ignore_characters.find(c) == ignore_characters.end())
{
// check if the set contains the character, in C++20 : seen_characters.contains(c)
// and maybe you need to do something with "std::tolower()" here too
if (seen_characters.find(c) != seen_characters.end())
{
return true;
}
// add the character to the set, we've now seen it
seen_characters.insert(c);
}
}
return false;
}
void show_has_repeated_characters(const std::string& input)
{
std::cout << "'" << input << "' ";
if (has_repeated_characters(input))
{
std::cout << "has repeated characters\n";
}
else
{
std::cout << "doesn't have repeated characters\n";
}
}
int main()
{
show_has_repeated_characters("Hello world");
show_has_repeated_characters("The fast boy");
return 0;
}
std::string str;
... fill your string here...
int counts[256]={0};
for(auto s:str)
counts[(unsigned char)s]++;
for(int i=0;i<256;i++)
if(counts[i]>1) return true;
return false;
6 lines instead of 9
O(n+256) instead of O(n^2)
This is your new compact function :
#include <iostream>
#include <algorithm>
using namespace std;
int occurrences(string s, char c) {
return count(s.begin(), s.end(), c); }
int main() {
//occurrences count how many times char is repetated.
//any number other than 0 is considered true.
occurrences("Hello World!",'x')?cout<<"repeats!":cout<<"no repeats!";
//It is equal write
//
// if(occurrences("Hello World!",'x'))
// cout<<"repeats!";
// else
// cout<<"no repeats!";
//So to count the occurrences
//
// int count = occurrences("Hello World!",'x');
}

Error "no match for 'operator+" when concatenating strings

I am trying to reverse the words in a string using this code:
#include <bits/stdc++.h>
using namespace std;
int main()
{
//_ _ the sky is blue
string vec;
getline(cin, vec);
stack<string> str;
string temp = "";
string ans = "";
for (int i = 0; i < vec.length(); i++)
{
if (vec.at(i) == ' ')
{
if (temp.length() > 0)
{
str.push(temp);
temp = "";
}
else
{
temp = temp + vec.at(i);
}
}
}
//ans = ans + temp;
while (!str.empty())
{
ans = ans + " " + str.pop();
}
if (ans.length() != 0 && ans.at(0) == ' ')
ans = ans.substr(1);
cout << ans << endl;
}
I'm receiving this error at line 33 telling "no match for 'operator+'".
I have attached the relevant screenshot:
Please, help.
pop() is a stack member method with void return type, it doesn't return a string, therefore it cannot be printed neither can it be concatenated with other strings.
As the error shows you you can't add void and string using + operator for these 2 different types (unless you made that option available by overloading the + operator), so ans = ans + " " + str.pop(); is wrong.
You could use:
while (!str.empty())
{
ans = ans + " " + str.top();
str.pop();
}
As top() does return a string object.
I should point out that using #include <bits/stdc++.h> is bad and using namespace std is also not very good, but bringing them together is a disaster waiting to happen.
The method pop of the container adapter std::stack has the return type void. So this statement
ans= ans+" "+str.pop();
is incorrect and the compiler will issue an error.
You need to write something like
while(!str.empty()){
ans= ans+" "+ str.top();
str.pop();
}
Pay attention to that this for loop
for(int i=0 ; i<vec.length(); i++){
if(vec.at(i)==' '){
if(temp.length()>0){
str.push(temp);
temp = "";
}
else{
temp = temp + vec.at(i);
}
}
}
has a bug. If the string stored in the object vec does not end with a space character then the last word of the string will not be pushed on the stack.
It seems what you are trying to do is the following.
#include <iostream>
#include <string>
#include <stack>
#include <cctype>
int main()
{
std::string s( " Hello World " );
std::stack<std::string> st;
std::cout << "\"" << s << "\"\n";
for ( std::string::size_type i = 0; i < s.size(); )
{
std::string tmp;
while ( i < s.size() && isspace( ( unsigned char )s[i] ) )
{
tmp += s[i++];
}
if ( !tmp.empty() )
{
st.push( tmp );
tmp.clear();
}
while ( i < s.size() && !isspace( ( unsigned char )s[i] ) )
{
tmp += s[i++];
}
if ( !tmp.empty() )
{
st.push( tmp );
}
}
std::string result;
while ( !st.empty() )
{
result += st.top();
st.pop();
}
std::cout << "\"" << result << "\"\n";
return 0;
}
The program output is
" Hello World "
" World Hello "
Thank you guys for helping me out. Here's code and working perfectly fine:
#include <bits/stdc++.h>
using namespace std;
int main(){
//_ _ the sky is blue
string vec;
getline(cin, vec);
stack<string>str;
string rs;
string temp="";
string ans= "";
for(int i=0 ; i<vec.length(); i++){
if(vec.at(i)==' '){
if(temp.length()>0){
str.push(temp);
temp = "";
}
}
else{
temp = temp + vec.at(i);
}
}
ans = ans + temp;
while(!str.empty()){
ans= ans+" "+str.top();
str.pop();
}
if(ans.length() != 0 && ans.at(0) == ' '){
ans = ans.substr(1);
}
cout<<ans<<endl;
reverse( ans.begin(), ans.end());
cout<<ans<<endl;
}
Here is the output which only allows single space between each words and eliminates both leading and trailing space:

Remove adjacent Duplicates from a String which have count greater than or equal to burst Length

Given a string with repeating characters and a burst length, output the string such that the count of the same adjacent characters in the string is less than the burst length.
Input : abbccccdd, burstLen = 3
Correct Output : abbdd
My Output: abbd
Input : abbcccdeaffff, burstLen = 3
Correct Output: abbdea
My Output: abbea
//Radhe krishna ki jytoi alokik
#include <bits/stdc++.h>
using namespace std;
string solve(string s, int burstLen)
{
stack<pair<char, int>> ms;
for (int i = 0; i < s.size(); i++)
{
if (!ms.empty() && ms.top().first == s[i])
{
int count = ms.top().second;
ms.push({s[i], count + 1});
}
else
{
if(ms.empty() == true || ms.top().first != s[i])
{
if(!ms.empty() && ms.top().second >= burstLen)
{
int count = ms.top().second;
while(!ms.empty() && count--)
ms.pop();
//(UPDATE)
ms.push({s[i], 1});
}
else
ms.push({s[i], 1});
}
}
}
if(!ms.empty() and ms.top().second >= burstLen)
{
int count = ms.top().second;
while(!ms.empty() && count--)
ms.pop();
}
string ans = "";
while (!ms.empty())
{
ans += ms.top().first;
ms.pop();
}
reverse(ans.begin(), ans.end());
return ans;
}
int main()
{
string s;
int burstLen;
cin >> s;
cin >> burstLen;
cout << solve(s, burstLen) << "\n";
}
It would be better at least to use the container adapter std::queue instead of std::stack because there would not be a need to call the algorithm std::reverse.
Moreover if items of the stack contain the second data member that stores frequencies then you could just increase this data member for repeated characters instead of placing each repeated character in the stack.
For example this code snippet in your program
if (!ms.empty() && ms.top().first == s[i])
{
int count = ms.top().second;
ms.push({s[i], count + 1});
}
makes the function definition too complicated and unclear because the same character is pushed on the stack with different frequencies.
Nevertheless if you want to use the container adapter std::stack the function definition could look simpler. You are not using features of the class std::string.
Here is a demonstrative program that shows how the function could be written using your approach with std::stack.
#include <iostream>
#include <string>
#include <utility>
#include <stack>
#include <iterator>
#include <algorithm>
std::string solve( const std::string &s, size_t burstLen )
{
std::stack<std::pair<char, size_t>> stack;
for ( const auto &c : s )
{
if ( stack.empty() || stack.top().first != c )
{
stack.push( { c, 1 } );
}
else
{
++stack.top().second;
}
}
std::string ans;
while ( !stack.empty() )
{
if ( stack.top().second < burstLen )
{
ans.append( stack.top().second, stack.top().first );
}
stack.pop();
}
std::reverse( std::begin( ans ), std::end( ans ) );
return ans;
}
int main()
{
std::cout << solve( "abbccccdd", 3 ) << '\n';
std::cout << solve( "abbcccdeaffff", 3 ) << '\n';
}
The program output is
abbdd
abbdea
It is interesting to use the stack when after removing a sequence of characters that is not less than the burst length you get from the left and right side sub-sequences anew sequence that again is not less than burst length and you need also to remove it.
In this case you can use two stacks.
Here is a demonstrative program.
#include <iostream>
#include <string>
#include <utility>
#include <stack>
#include <iterator>
#include <algorithm>
std::string solve( const std::string &s, size_t burstLen )
{
std::stack<std::pair<char, size_t>> stack_in;
for ( const auto &c : s )
{
if ( stack_in.empty() || stack_in.top().first != c )
{
stack_in.push( { c, 1 } );
}
else
{
++stack_in.top().second;
}
}
std::stack<std::pair<char, size_t>> stack_out;
while ( !stack_in.empty() )
{
if ( !stack_out.empty() && stack_out.top().first == stack_in.top().first )
{
if ( stack_out.top().second + stack_in.top().second < burstLen )
{
stack_out.top().second += stack_in.top().second;
}
else
{
stack_out.pop();
}
}
else if ( stack_in.top().second < burstLen )
{
stack_out.push( stack_in.top() );
}
stack_in.pop();
}
std::string ans;
while ( !stack_out.empty() )
{
ans.append( stack_out.top().second, stack_out.top().first );
stack_out.pop();
}
return ans;
}
int main()
{
std::cout << solve( "abbccccdd", 3 ) << '\n';
std::cout << solve( "abbcccdeaffff", 3 ) << '\n';
std::cout << solve( "aabcddeeedccbaa", 3 );
}
The program output is
abbdd
abbdea
aabbaa
I gave it a try but it looks complicated so I suggest making a simpler function using a few functions from the standard library.
Example:
#include <algorithm>
#include <iostream>
#include <initializer_list>
#include <iterator>
std::string solve(const std::string& in, size_t burstlen) {
std::string retval;
for(std::string::const_iterator begin = in.cbegin(), bend;
begin != in.end();
begin = bend)
{
// find the first char not equal to the current char
bend = std::find_if_not(std::next(begin), in.end(),
[curr=*begin](char ch){ return ch==curr; });
if(std::distance(begin, bend) < burstlen) {
// length ok, append it
retval.append(begin, bend);
}
}
return retval;
}
int main() {
std::initializer_list<std::string> tests{
"abbccccdd", "abbcccdeaffff"};
for(auto test : tests) std::cout << solve(test, 3) << '\n';
}
Output:
abbdd
abbdea
My Approach to the Solution :
Create a Stack of pair which consists of character and character count
If the Stack is empty or the top element of the stack is not equal to the current element in the string
Case 1: if the frequency of the top element of the stack is greater than or equal to k, store it in a variable say count, Pop the element of Stack count times.
Case 2: if the Stack is Empty, then simply push the element in stack with frequency 1.
Upon Traversing the complete string, if the top element of the stack is having a frequency greater than bursten, start removing elements from the stack (count) number of times.
Now, we have leftout elements in the stack, Start popping them and store them in a string and reverse the string to preserve the order.
Return the new string.
UPDATE : SOLVED. Missing one line in this condition if(ms.empty() == true || ms.top().first != s[i]) After popping the elements, We also have to insert the present element with character frequency 1.
#include<iostream>
#include<stack>
using namespace std;
string solve(string s, int burstLen)
{
stack<pair<char, int>> ms;
for (int i = 0; i < s.size(); i++)
{
if (!ms.empty() && ms.top().first == s[i])
{
int count = ms.top().second;
ms.push({s[i], count + 1});
}
else
{
if(ms.empty() == true || ms.top().first != s[i])
{
if(!ms.empty() && ms.top().second >= burstLen)
{
int count = ms.top().second;
while(!ms.empty() && count--)
ms.pop();
ms.push({s[i], 1});
}
else
ms.push({s[i], 1});
}
}
}
if(!ms.empty() and ms.top().second >= burstLen)
{
int count = ms.top().second;
while(!ms.empty() && count--)
ms.pop();
}
string ans = "";
while (!ms.empty())
{
ans += ms.top().first;
ms.pop();
}
reverse(ans.begin(), ans.end());
return ans;
}
int main()
{
int t;
cin >> t;
while(t--)
{
string s;
int burstLen;
cin >> s >>burstLen;
cout << solve(s, burstLen) << "\n";
}
}
private void solve(){
System.out.printf("%s\n", solve("abbccccdd", 3));
System.out.printf("%s\n", solve("abbcccdeaffff", 3));
}
private LinkedList<Node> addToQueue(String S){
int N = S.length();
LinkedList<Node> queue = new LinkedList<>();
queue.addFirst(new Node(S.charAt(0), 1));
for(int i=1;i<N;i++){
if(!queue.isEmpty() && queue.getFirst().val==S.charAt(i)) {
queue.getFirst().count +=1;
} else {
queue.addFirst(new Node(S.charAt(i), 1));
}
}
return queue;
}
private String solve(String S, int K){
if(S==null || S.length()==0) return "";
int N = S.length();
LinkedList<Node> queue = addToQueue(S);
StringBuilder buf = new StringBuilder();
while(!queue.isEmpty()) {
Node node = queue.removeLast();
int count = node.count;
if(count>=K) continue;
if(isSame(queue, buf)){
while(isSame(queue, buf)) {
count += queue.getLast().count;
queue.removeLast();
}
if(count>=K) buf.deleteCharAt(buf.length()-1);
else {
while(count-->0){
buf.append(node.val);
}
}
} else {
if(count>=K) continue;
while(count-->0){
buf.append(node.val);
}
}
}
return buf.toString();
}
private boolean isSame(LinkedList<Node> queue, StringBuilder buf){
if(queue.isEmpty() || buf.length()==0) return false;
return queue.getLast().val == buf.charAt(buf.length()-1);
}
class Node {
char val;
int count;
public Node(char c, int count){
this.val = c;
this.count = count;
}
}

Remove duplicates from the string in CPP

I wrote the following code for removing the duplicates from a given string i.e. if ARRUN is the input then the output will be ARUN.
#include <bits/stdc++.h>
using namespace std;
char* removeDuplicates(string &s,int n){
char arr[n];
unordered_map<char,int> exists;
int index = 0;
for(int i=0;i<n;i++){
if(exists[s[i]]==0)
{
arr[index++] = s[i];
exists[s[i]]++;
}
}
return arr;
}
//driver code
int main(){
string str;
cin >> str;
cout<<removeDuplicates(str,str.length())<<endl;
return 0;
}
The code produces no output at all, however, it works fine if I use char arr[] instead of string class.
You can't use char arr[n] without being n constant or constexpr.
You don't need map. set is sufficient.
Note that map and set remove duplicates already, then you can check if any element is inserted or not to get your new string in the same order of the first, as follows
#include<string>
#include<iostream>
#include<unordered_set>
std::string removeDuplicates(const std::string &s){
std::string arr;
std::unordered_set<char> exists;
for(const auto&el:s)
if(exists.insert(el).second) arr+=el;
return arr;
}
//driver code
int main(){
std::string str;
std::cin >> str;
std::cout<<removeDuplicates(str)<<std::endl;
return 0;
}
std::string support removing elements.
#include <iostream>
#include <string>
std::string removeDuplicates(std::string str) {
for (int i = 0; i < str.size(); i++) {
while (true) {
int j = str.find_last_of(str[i]);
if (i < j) {
str.erase(j, 1);
} else {
break;
}
}
}
return str;
}
int main() {
std::cout << removeDuplicates("ARRUN");
return 0;
}
If a function declaration looks the following way
char* removeDuplicates(string &s,int n);
then it means that the passed object itself will be changed in the function. Otherwise the parameter shall have the qualifier const.
Also it is unclear why the function has return type char *. It looks like the declaration of the function is contradictive.
The second parameter of the function shall have at least the type size_t or that is better std::string::size_type. The type int can not accomodate all values of the type std::string::size_type.
The function could be declared without the second parameter.
A straightforward approach without using intermediate containers that requires dynamic memory allocation can look the following way
#include <iostream>
#include <string>
std::string & removeDuplicate( std::string &s )
{
const char *p = s.c_str();
std::string::size_type pos = 0;
for ( std::string::size_type i = 0, n = s.size(); i < n; i++ )
{
std::string::size_type j = 0;
while ( j < pos && s[i] != s[j] ) j++;
if ( j == pos )
{
if ( i != pos ) s[pos] = s[i];
++pos;
}
}
return s.erase( pos );
}
int main()
{
std::string s( "H e l l o" );
std::cout << "\"" << s <<"\"\n";
std::cout << "\"" << removeDuplicate( s ) <<"\"\n";
return 0;
}
The program output is
"H e l l o"
"H elo"
#Arun Suryan, You pointed out correctly. But you can do it without using vector by using global char array.
Also don't forget to append the newline at the end!
Have a look at the following code:
#include<string>
#include<iostream>
#include<unordered_map>
char* removeDuplicates(std::string &s,int n){
std::unordered_map<char,int> exists;
char* arr = (char*)(malloc(n*sizeof(char)));
int index = 0;
for(int i=0;i<n;i++){
if(exists[s[i]]==0)
{
arr[index++] = s[i];
exists[s[i]]++;
}
}
arr[index] = '\n';
return arr;
}
//driver code
int main(){
std::string str;
std::cin >> str;
std::cout<<removeDuplicates(str,str.length())<<std::endl;
return 0;
}
This might be a bit advanced for newcomers to C++ but another solution makes use of the erase-remove idiom:
std::string removeDuplicates(const std::string& s) {
std::string result = s;
std::unordered_set<char> seen;
result.erase(std::remove_if(result.begin(), result.end(), [&seen](char c)
{
if (seen.find(c) != seen.end())
return true;
seen.insert(c);
return false;
}),
result.end());
return result;
}
It basically uses a set to store characters that have been seen, shuffles the characters to be removed down to the tail (using std::remove_if) and erases the tail from the string.
Working version here.
This works too, a single line solution with an inbuild function.
cout<<str.erase(std::unique(str.begin(), str.end()), str.end());
Simple Answer
#include<bits/stdc++.h>
using namespace std;
string removeduplicate(string key){
set<char>s;
string ans="";
for(int i=0;i<key.size();++i){
if(s.find(key[i])==s.end()){
s.insert(key[i]);
ans.push_back(key[i]);
}
}
return ans;
}
int main()
{
string key="";
cout<<"enter the key:";
cin>>key;
string ans1=removeduplicate(key);
cout<<ans1;
return 0;
}
So, after doing a bit of reading on the Internet I realized that I was trying to return a pointer to the local array in the removeDuplicates() function.
This is what works fine
#include <bits/stdc++.h>
using namespace std;
void removeDuplicates(string &s,int n){
vector<char> vec;
unordered_map<char,int> exists;
int index = 0;
for(int i=0;i<n;i++){
if(exists[s[i]]==0)
{
vec.push_back(s[i]);
exists[s[i]]++;
}
}
for(auto x: vec)
cout << x;
}
//driver code
int main(){
string str;
cin >> str;
removeDuplicates(str,str.length());
return 0;
}
PS: We can make the return type of function to vector as well.

converting strings to integers by using "stringstream "

I am trying to convert strings of data to integers, (to use it for some calculations ) by using stringstream , but it fails when there is a space.
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
int main() {
string line;
vector <string>data;
for (int i = 0; i < 10;i++) {
getline(cin,line);
data.push_back(line);
}
///converting digits to int
vector<int> values;
int n;
char ch=',';
for (int i = 0; i < data.size();i++) {
stringstream stream(data[i]);
while( stream >>n ) {
if(stream >> ch) {
values.push_back(n);
}
else {
values.push_back(n);
}
cout<<n<<" ";
}
cout<<endl;
}
return 0;
}
input : 1,182,08 51 15 --> output : 1 182 8 1 5
there are some digits lost after spaces.
so, what can I do to avoid it?
Complete working code based on seccpur's answer. Visual Studio 2017 Community:
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
#define BUFSZ 100 // Set max size of the numbers as a single string
int convertToIntegers(char *s, vector<int> &values);
int main()
{
int count;
int i;
char data[BUFSZ];
vector<int> values;
strcpy_s(data, "1,182,08 51 15");
count = convertToIntegers(data, values);
// for (auto val : values) // Show the result
// cout << val << '\n';
// *** OR ***
for (i = 0; i < count; i++)
cout << values[i] << '\n';
}
//////////////////////////////////////
// Convert a C string to integers
//
int convertToIntegers(char *s, vector<int> &values)
{
vector<string> numbers;
char *next_token;
char* ptr = strtok_s(s, " -.,;", &next_token);
while (ptr)
{
string str(ptr);
numbers.push_back(str);
ptr = strtok_s(NULL, " -.,;", &next_token); // Next number
}
//
// Convert the resulting strings to integers
//
for (auto str : numbers)
values.push_back(stoi(str));
return (int)values.size();
}
If you know you have exactly one character as a separator, either a space, either a comma, the following code will work:
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
int main() {
string line;
vector <string>data;
for (int i = 0; i < 10;i++) {
getline(cin,line);
data.push_back(line);
}
///converting digits to int
vector<int> values;
int n;
char ch=',';
for (int i = 0; i < data.size();i++) {
stringstream stream(data[i]);
while( stream >>n ) {
char c = stream.get();
//if(stream >> ch) {
// values.push_back(n);
//}
//else {
values.push_back(n);
//}
cout<<n<<" ";
}
cout<<endl;
}
return 0;
}
You are using multiple delimiters in the input ( like whitespace : , ; -) which complicates the matter. Here's a possible snippet using std::strtok:
//Enter a line
string line;
getline(cin, line);
// Convert string to char* so that std::strtok could be used later
char *cstr = new char[line.length() + 1];
std::strcpy(cstr, line.c_str());
vector<string> words;
// split line into multiple strings using multiple delimiters
char* ptr = std::strtok(cstr, " -.,;");
while (ptr)
{
string str(ptr);
words.push_back(str);
ptr = strtok(NULL, " -.,;");
}
delete[] cstr;
// Convert string to int
vector<int> values;
for (auto str : words){
values.push_back(std::stoi(str));
}
// Print the values
for (auto val : values){
cout << val << '\n';
}