This question already has answers here:
How do I iterate over the words of a string?
(84 answers)
Closed 9 years ago.
I am having problems splitting a string using pure C++
The string always looks like this
12344//1238
First int then // and then the second int.
Need help to get the two int values and ignore the //
string org = "12344//1238";
size_t p = org.find("//");
string str2 = org.substr(0,p);
string str3 = org.substr(p+2,org.size());
cout << str2 << " "<< str3;
why cant we use sscanf?
char os[20]={"12344//1238"};
int a,b;
sscanf(os,"%d//%d",a,b);
Reference
Take a look at the strtok function
This should Split and convert to integers:
#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>
class BadConversion : public std::runtime_error {
public:
BadConversion(std::string const& s)
: std::runtime_error(s)
{ }
};
inline double convertToInt(std::string const& s,
bool failIfLeftoverChars = true)
{
std::istringstream i(s);
int x;
char c;
if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
throw BadConversion("convertToInt(\"" + s + "\")");
return x;
}
int main()
{
std::string pieces = "12344//1238";
unsigned pos;
pos = pieces.find("//");
std::string first = pieces.substr(0, pos);
std::string second = pieces.substr(pos + 2);
std::cout << "first: " << first << " second " << second << std::endl;
double d1 = convertToInt(first), d2 = convertToInt(second) ;
std::cout << d1 << " " << d2 << std::endl ;
}
Simplest way I can think of:
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
void main ()
{
int int1, int2;
char slash1, slash2;
//HERE IT IS:
stringstream os ("12344//1238");
os>> int1 >> slash1 >> slash2 >> int2;
//You may want to verify that slash1 and slash2 really are /'s
cout << "I just read in " << int1 << " and " << int2 << ".\n";
system ("pause");
}
Also nice because it's so easy to rewrite -- if, say, you decide to read in ints delimited by something else.
Take the integers in as a string.
The string will then have the numbers and the // symbols.
Next you can run a simple for loop looking for the '/' in the string.
The values prior to the symbol are stored in another string.
When '/' appears, the for loop will terminate. You now have the index of the first
'/' symbol.
Increment the index and copy the rest of the string using anothe for loop, in another
string.
Now you have two separate strings.
Related
I wrote this code to remove all occurrences of x from the string using recursion
#include <bits/stdc++.h>
using namespace std;
void removex(string str)
{
if (str.length()==0)
{
return;
}
if (str[0] != 'x')
{
removex(str.substr(1,str.length()));
}
int i = 1;
for (; str[i] != '\0'; i++)
{
str[i-1]=str[i];
}
str[i - 1] = str[i];
removex(str);
// cout<<"strq"<<str<<endl;
}
int main()
{
int t;
cin >> t;
while (t--)
{
string str;
cin >> str;
removex(str);
cout << str << endl;
}
return 0;
}
however it's pass by value and If I try using pass by reference it gives an error as
initial value of reference to non-const must be an lvalueC. which means I need to make the reference constant which is not suitable for rest of the code. I tried pass by pointer and using arrow operator however unable to get value at index and not sure how to make recursion call. to pass address or ponter? can someone modify it accordingly?
Doing this with std::string and recursion is a formidable template for insanity. The erase/remove idiom exists for just this purpose, functions iteratively, and is highly efficient. Best of all, it already exists; all you have to do is set up the calls.
That said, if you're bent on doing this recursively (and inefficiently) you need to convey the result back to the caller (including the recursive calls) somehow. The following does that using the function return type, which is std::string. This also uses the global free operator + that allows concatenation of a char + std::string to return a new string:
#include <iostream>
#include <string>
std::string removex(std::string str)
{
if (!str.empty())
{
if (str[0] == 'x')
str = removex(str.substr(1));
else
str = str[0] + removex(str.substr(1));
}
return str;
}
int main()
{
std::string str = "Remove all x chars from this string.";
std::cout << "Before: " << str << '\n';
std::cout << "After: " << removex(str) << '\n';
return 0;
}
Output
Before: Remove all x chars from this string.
After: Remove all chars from this string.
That said, that isn't the way I'd do this. I'd use the erase/remove idiom which would be much faster, and much more memory efficient.
Given that you are using C++, I would use the features of the standard library. I believe this problem can be easily solved with a single line of code. Assuming that the string variable is called line, you would just need to do something like:
line.erase(remove(line.begin(), line.end(), 'x'), line.end());
Following is a complete example:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
std::string line = "12djd V x jhrf h58HSFH HUHFuhfdhkdh uhdfvygh 234 fhj xxx";
std::cout << "Line before removing the x character: " << line << std::endl;
line.erase(remove(line.begin(), line.end(), 'x'), line.end());
std::cout << "Line after removing the x character: " << line << std::endl;
return 0;
}
The example above would produce the following output:
Line before removing the x character: 12djd V x jhrf h58HSFH HUHFuhfdhkdh uhdfvygh 234 fhj xxx
Line after removing the x character: 12djd V jhrf h58HSFH HUHFuhfdhkdh uhdfvygh 234 fhj
An example that you can run is available here: https://onlinegdb.com/4wzMXTXP5
There is an exercise which dynamically asks for user input and stores in a vector, but I don't know how to end a string input. The book says it is Ctrl+Z but it doesn't work. I am using visual studio 2019 and I know it should work because when I change the variables for integers it does.
int main(void) {
std::vector<std::string> words;
for (std::string palabras; std::cin >> palabras;)
words.push_back(palabras);
std::string ban = "broccoli";
for (std::string x : words)
if (x == ban) std::cout << "Bleep!" << '\n';
else std::cout << x << '\n';
}
Keep things simple: don't use the return value of std::cin as the for loop condition, unless you're sure what to expect. Here is a simple program that does what you want without using a loop. It would be a good exercise to make that work inside a loop.
#include <iostream>
#include <string>
int main(int argc, char **argv)
{
std::string lovely_str;
std::cout << "Enter a string: ";
std::cin >> lovely_str;
std::cout << "got: " << lovely_str << "\n";
return 0;
}
If you insist on using your original program you can use ctrl+d
to signal the end of read strings
Take some help of std::istringstream & make life easier (notice comments):
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
int main(void) {
// To store the entire line of input
std::string input;
// To store the split words
std::vector<std::string> words;
// Temporary variable to iterate through
std::string temp;
// Constant string to be used
const std::string ban = "broccoli";
std::cout << "Enter some words: ";
std::getline(std::cin, input);
// Here we go
std::istringstream iss(input);
// Separating each words space, e.g. apple <sp> banana => vector apple|banana
while (iss >> temp)
words.push_back(temp);
// Using reference as for-each
for (auto& i : words)
if (i == ban) i = "bleep!";
// Printing the modified vector
for (auto& i : words) std::cout << i << ' ';
std::cout << std::endl;
return 0;
}
I am trying to allow the user to input a decent number of words (around 10-20) and then parse the input, but using the code below will wait until the user has input a value for every string.
Is there a way to make C++ auto fill the remaining strings with the null character or something similar so the entry of a number of words less than the max won't cause a holdup?
Code:
#include <iostream>
#include <string>
int main()
{
std::string test1;
std::string test2;
std::string test3;
std::cout << "Enter values\n:";
std::cin >> test1 >> test2 >> test3;
std::cout << "test1: " << test1 << " test2: " << test2 << " test3: " << test3 << std::endl;
}
To read (and store) and unknown number of whitespace separate strings, you need storage for each string. The most basic way to provide the storage in a flexible way that can be added to in an unlimited (up to your usable memory limit) is with a vector of strings. The string provides storage for each string and the vector container provides an easy way to collect any number of strings together.
Your vector-of-strings (vs) can be declared as:
#include <iostream>
#include <string>
#include <vector>
...
std::vector<std::string>vs {};
std::vector provides the .push_back() member function to add an element (a string in this case) to the vector, e.g.
std::vector<std::string>vs {};
std::string s;
while (std::cin >> s)
vs.push_back(s);
Which simply reads string s until EOF is encountered, and each string read is added to the vector-of-strings using vs.push_back(s);.
Putting it altogether you could do:
#include <iostream>
#include <string>
#include <vector>
int main (void) {
std::vector<std::string>vs {};
std::string s;
while (std::cin >> s) /* read each string into s */
vs.push_back(s); /* add s to vector of strings */
for (auto& w : vs) /* output each word using range-based loop */
std::cout << w << "\n";
}
Example Use/Output
$ echo "my dog has fleas" | ./bin/readcintostrings
my
dog
has
fleas
Look things over and let me know if you have further questions.
You can use while loop .Something like this
string s;
while (cin >> s) {
cout << s << endl;
}
or take a vector of strings and make a while , Take inputs in while loop and push them into vector.
as you see it doesn't store. if you want to store.
do
vector<string>text;
while(cin>>s){
text.push_back(s);}
I figured it out using this code:
#include <iostream>
#include <string>
int main()
{
std::string testTemp;
std::string brokenUp[20];
int lastOne = 0;
std::cout << "Enter values\n:";
std::getline(std::cin, testTemp);
for(int current = 0; !testTemp.empty() && testTemp.find(' ') != -1; current++)
{
brokenUp[current] = testTemp.substr(0, testTemp.find(' '));
testTemp.erase(0, testTemp.find(' ') + 1);
lastOne = current;
}
lastOne++;
brokenUp[lastOne] = testTemp;
//this next part is just a test
for(int i = 0; i <= lastOne; i++)
{
std::cout << brokenUp[i] << std::endl;
}
}
but you could use anything as the storage for the broken up strings (i.e. a list or a dynamic array).
I want to ask for word from the user and then convert the word from string to char using 'strcpy'. Then I want to determine the sum of the ascii codes for all of the letters in the word.
However, I am having difficulties. I don't understand exactly how I can do that. This is what I have been able to do so far.
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
int main()
{
string word;
cout << "Enter word: ";
getline(cin, word);
/*
char w[word];
strcpy(w,word.c_str());
int ('A');
cout<<char(65);
*/
return 0;
}
The commented part is where I have been trying to do the converting. I copied the code from a worksheet. Even if it did work, I don't know how, and what it all means.
Thanks for your help.
char w[word];
strcpy(w, word.c_str());
char w[word] is incorrect. The square brackets is for the size, which must be a constant integral expression. word is of type std::string, so this makes neither logical nor practical sense. Maybe you meant it as:
char w = word;
But that still won't work because word is a string, not a character. The correct code in this case is:
char* w = new char[word.size() + 1];
That is, you allocate the memory for w using a char*. Then you use word.size() + 1 to initialize heap-allocated memory amounting to those bytes. Don't forget for the obligatory delete[] when you're finished using w:
delete[] w;
However, note that using raw pointers and explicit new is not needed in this case. Your code can easily be cleaned up into the following:
#include <numeric>
int main ()
{
std::string word;
std::getline(std::cin, word);
int sum = std::accumulate(word.begin(), word.end(), 0); /*
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
std::cout << "The sum is: " << sum << std::endl;
}
You don't need to use strcpy() (or use a char * at all, for that matter), but this'll do your counting using a char pointer:
#include <iostream>
#include <string>
int main() {
std::string word;
std::cout << "Enter word: ";
std::cin >> word;
const char * cword = word.c_str();
int ascii_total = 0;
while ( *cword ) {
ascii_total += *cword++;
}
std::cout << "Sum of ASCII values of characters is: ";
std::cout << ascii_total << std::endl;
return 0;
}
Output:
paul#local:~/src/cpp/scratch$ ./asccount
Enter word: ABC
Sum of ASCII values of characters is: 198
paul#local:~/src/cpp/scratch$
If you really do want to use strcpy(), I'll leave it as an exercise to you to modify the above code.
Here's a better way to do it, just using std::string (and C++11, and obviously presuming your system uses the ASCII character set in the first place):
#include <iostream>
#include <string>
int main() {
std::string word;
std::cout << "Enter word: ";
std::cin >> word;
int ascii_total = 0;
for ( auto s : word ) {
ascii_total += s;
}
std::cout << "Sum of ASCII values of characters is: ";
std::cout << ascii_total << std::endl;
return 0;
}
How do I get a part of a string in C++? I want to know what are the elements from 0 to i.
You want to use std::string::substr. Here's an example, shamelessly copied from http://www.cplusplus.com/reference/string/string/substr/
// string::substr
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str="We think in generalities, but we live in details.";
// quoting Alfred N. Whitehead
string str2, str3;
size_t pos;
str2 = str.substr (12,12); // "generalities"
pos = str.find("live"); // position of "live" in str
str3 = str.substr (pos); // get from "live" to the end
cout << str2 << ' ' << str3 << endl;
return 0;
}
You use substr, documented here:
#include <iostream>
#include <string>
using namespace std;
int main(void) {
string a;
cout << "Enter string (5 characters or more): ";
cin >> a;
if (a.size() < 5)
cout << "Too short" << endl;
else
cout << "First 5 chars are [" << a.substr(0,5) << "]" << endl;
return 0;
}
You can also then treat it as a C-style string (non-modifiable) by using c_str, documented here.
If the string is declared as an array of characters, you can use the following approach:
char str[20];
int i;
strcpy(str, "Your String");
// Now let's get the sub-string
cin >> i;
// Do some out-of-bounds validation here if you want..
str[i + 1] = 0;
cout << str;
If you mean std::string, use substr function as Will suggested.
Assuming you're using the C++ std::string class
you can do:
std::string::size_type start = 0;
std::string::size_type length = 1; //don't use int. Use size type for portability!
std::string myStr = "hello";
std::string sub = myStr.substr(start,length);
std::cout << sub; //should print h
use:
std::string sub_of_s(s.begin(), s.begin()+i);
which create a string sub_of_s which is the first i-th the element in s.