Terminate string input in a vector loop C++ - c++

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;
}

Related

why is this code not giving the desired output?

#include <sstream>
#include <vector>
#include <iostream>
using namespace std;
vector<int> parseInts(string str) {
istringstream ss(str);
vector<int> integ;
int val;
while(ss){
if(ss>>val){
integ.push_back(val);
}
}
return integ;
}
vector<int> parseInts2(string str)
{
vector<int> vec;
stringstream ss(str);
char ch;
int temp;
while(ss)
{
ss>>temp>>ch; >> operator
vec.push_back(temp);
}
return vec;
}
int main() {
string str;
cin >> str;
vector<int> integers = parseInts(str);
for(int i = 0; i < integers.size(); i++) {
cout << integers[i] << "\n";
}
return 0;
}
i want to create a stream,to a string,read integers to the stream from the string and insert it in a vector and display its elements while the output is displaying nothing.what is wrong with the code?
EDIT
basically the question ask inputs in the form of integers that are separated by commas and asks us to print the integers after parsing it. i find no significant difference between the 2 functions but parseInt2 still works(while calling the function in main,of course instead of parseInt). Why?
I fear that your question will be closed by people on SO.
But let me give you the answer.
Basically everything set already in the comments. Why not in an answer? I do not know.
Before you can read something from an std::istringstream, you need to put something in it. You need to initialize it. That is usually done by using its constructor:
istringstream ss(str);
In main, you have the problem, that you read only one value from std::cin with cin >> str;. You want to use std::getline instead, which reads a complete line. And not only "something" up to the next space. So
getline(cin, str);
will help you further.
In modern C++, with keeping the std::istringstream approach, you would probably write
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <sstream>
int main() {
// Read a line and check, if that worked
if (std::string str; std::getline(std::cin, str)) {
// Create and initialize a std::istringstream
std::istringstream iss(str);
// Define a variable integers, use its range constructor with iterators
std::vector integers(std::istream_iterator<int>(iss), {});
// Range based for loop
for (const int& i : integers) {
std::cout << i << "\n";
}
}
return 0;
}
That will save the subfunction.
EDIT:
OK, you want to read csv and you must use ">>".
If you want to read data separated by comma from a stream, then you need to extract:
an integer value from the stream
then a comma
then a integer
then a comma
then a integer
. . .
The extractor operator, or the functionality behind it, will always extract characters from a stream and convert it to a requested type (e.g. an integer), until it reaches a space or the conversion can not be continued any longer (for example, a "," is a separator).
That is the reason, why your 2nd function works.
It is important that you alwys check the status of the extraction operation. In the below example you will see that, at the end of the string, we try to read a comma, where there is none. The extraction fails, but we do not care. We ignore it by intent. To understand the functionality better, please see.
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
int main() {
// Source or test data. We put it directly into the stream;
std::istringstream ss{ "1,2,3, 4 , 5,6" };
std::vector<int> integers{};
char comma{};
int integer{};
while (ss) {
// Read integer and check, if it could be read
if (ss >> integer) {
integers.push_back(integer);
std::cout << "Read Integer " << integer << "\n";
}
else
std::cerr << "Error: Could not read integer\n";
// Now read the comma
if (ss && (ss >> comma))
std::cout << "Read Comma: " << comma << "\n";
else
std::cerr << "Error: Could not read comma\n";
}
// SHow all values
for (const int i : integers) std::cout << i << "\n";
return 0;
}
If you have questions, I am happy to answer.

Is there a way to make C++ take in an undefined number of strings from cin?

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).

How to get the strings to print in order after they have been reversed

The goal of this program is to get user input and then print the words backwards, but still in the order the user typed them in. For example, the user input- "cats and mice are cool", then the program should output "stac dna ecim era looc", but what I am getting is "looc era ecim dna stac". I think that rearranging the words would happen in the main function, but I'm not sure how to get it to print in order. Any help greatly appreciated!
#include <iostream>
#include <cstring>
using namespace std;
void reverse(string input) {
int size = (int)input.size();
if(size==1){
cout << input[size-1];
}
else {
cout << input[size-1];
reverse(input.substr(0, size-1));
}
}
int main() {
string input;
char choice;
cout << "Please enter a string with spaces." << endl;
getline(cin, input);
reverse(input);
cout << endl;
}
You're reversing the entire string... split string on spaces, then cycle on splits and call reverse() on every split before printing it.
Furthermore, you can use C++ STL classes for reversing and even result useful in splitting:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
std::vector<std::string> split(std::string text, char delimiter)
{
std::vector<std::string> res;
std::istringstream f(text);
std::string s;
while (std::getline(f, s, delimiter)) {
res.push_back(s);
}
return(res);
}
int main() {
std::string input;
std::cout << "Please enter a string with spaces." << std::endl;
std::getline(std::cin, input);
for(auto s : split(input, ' '))
{
std::reverse(s.begin(), s.end());
std::cout << s << " ";
}
std::cout << std::endl;
}

C++ Replacing a word in an array of characters

I'm working on a problem where I need to have user input a message then replace the work "see" with "c". I wanted to read in the array message[200] and then break it down into individule words. I tried a for loop but when I concatinate it just adds the privous words. I am only to use array of characters, no strings.
const int MAX_SIZE = 200;
int main(){
char message[MAX_SIZE]; //message array the user will enter
int length; // count of message lenght
int counter, i, j; //counters for loops
char updateMessage[MAX_SIZE]; //message after txt update
//prompt user to
cout << "Please type a sentence" << endl;
cin.get(message, MAX_SIZE, '\n');
cin.ignore(100, '\n');
length = strlen(message);
//Lower all characters
for( i = 0; i < length; ++i)
{
message[i] = tolower(message[i]);
//echo back sentence
cout << "You typed: " << message << endl;
cout << "Your message length is " << length << endl;
for( counter = 0; counter <= length; ++counter)
{
updateMessage[counter] = message[counter];
if(isspace(message[counter]) || message[counter] == '\0')
{
cout << "Space Found" << endl;
cout << updateMessage << endl;
cout << updateMessage << " ** " << endl;
}
}
return 0;
}
After each space is found I would like to output one work each only.
You should really try to learn some modern C++ and standard library features, so you don't end up writing C code in C++. As an example, this is how a C++14 program makes use of standard algorithms from the library to do the job in 10-15 lines of code:
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
int main()
{
using namespace std::string_literals;
std::istringstream input("Hello I see you, now you see me");
std::string str;
// get the input from the stream (use std::cin if you read from console)
std::getline(input, str);
// tokenize
std::vector<std::string> words;
std::istringstream ss(str);
for(std::string word ; ss >> word; words.push_back(word));
// replace
std::replace(words.begin(), words.end(), "see"s, "c"s);
// flatten back to a string from the tokens
str.clear();
for(auto& elem: words)
{
str += elem + ' ';
}
// display the final string
std::cout << str;
}
Live on Coliru
This is not the most efficient way of doing it, as you can perform replacement in place, but the code is clear and if you don't need to save every bit of CPU cycles it performs decently.
Below is a solution that avoids the std::vector and performs the replacement in place:
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
int main()
{
std::istringstream input("Hello I see you, now you see me");
std::string str;
// get the input from the stream (use std::cin if you read from console)
std::getline(input, str);
// tokenize and replace in place
std::istringstream ss(str);
std::string word;
str.clear();
while (ss >> word)
{
if (word == "see")
str += std::string("c") + ' ';
else
str += word + ' ';
}
// display the final string
std::cout << str;
}
Live on Coliru

Convert string to char for ascii

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;
}