How can I get the number of characters from an input string? - c++

I am trying to count the number of characters in a string that is provided by the user. I know I can use string::length() and string::size() but when a space is encountered, the count is stopped. For example, say the user inputs "Bob Builder", the count should be 10 but what my code would display would be 3. Also I am trying to do this without using a character array. Any suggestions? An explanation would also greatly help.
int main()
{
string Name;
cin>>Name;
cout << name(Name);
return 0;
}
int name(string a)
{
int numChar;
/*for (int i=0; a[i] != '\0';i++)
{
if (!isspace(a[i]))
numChar++;
}*/
numChar=a.length();
return numChar;
}

How yu know when input is over?
If you want to read until end of line then this is a possible solution:
std::string line ;
std::cin.getline(line) ;
line.length() ;

You have to use getline() instead of cin to get all line up to newline. cin reads input up to whitespace.
std::getline (std::cin,Name);
If you use using namespace std;
getline (cin,Name);
If you want to count the input string excluding spaces, the code snippet helps you.
#include <algorithm>
#include <string>
int main()
{
std::string s = "Hello there, world!";
std::cout << std::count( s.begin(), s.end(), ' ' ) << std::endl;
}

Related

Stringstream parse comma-separated integers

So guys, Actually What I wanna do here is that when I input 3,12,36 the output will be:
3
12
36
But here I have difficulty on how to make it output all the answer. What I have been doing is that when you input 3,12,36 it will output 3 12 only and if you type 3,12,36,48 it will output 3 12 36.
So it will always miss the last integer because my while loop is not correct I guess. but if I change it into
while(output >> life|| output >> ch)
It doesn't work either. I've done a lot of research but it still makes me confused and I'm still stuck on this part.
vector<int> parseInts(string str) {//23,4,56
vector<int>lifeishard;
stringstream output;
string lifeisgood = str;
output.str(lifeisgood);
int life;
char ch;
while(output >> life >> ch){
lifeishard.push_back(life);
//lifeishard.push_back(life2);
//lifeishard.push_back(life3);
}
return lifeishard;
}
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;
}
On your last number, the while loop fails because there's no character at the end. Just the end of the string. So it doesn't execute the push_back inside the loop.
Change it so that the while loop just gets the number. Then do the push_back in the loop. Then in the loop, after the push, get the comma character. Don't bother checking for failure getting the comma because when it goes around the while loop again it will fail and exit.
I changed to using getline in your main. I changed your loop index to size_t because it is never a good idea to mix signed and unsigned integers, and whenever you use a size() function, it's a size_t. When posting your program it really should include everything. My fixed up version of your program:
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
vector<int> parseInts(string str) {//23,4,56
vector<int>lifeishard;
stringstream output;
string lifeisgood = str;
output.str(lifeisgood);
int life;
char ch;
while(output >> life){
lifeishard.push_back(life);
output >> ch;
}
return lifeishard;
}
int main() {
string str;
getline(cin, str);
vector<int> integers = parseInts(str);
for(size_t i = 0; i < integers.size(); i++) {
cout << integers[i] << "\n";
}
// Here is how we do for loops over containers in modern C++
for(auto x: integers) {
cout << x << '\n';
}
return 0;
}
A combination of stringstream, getline with delimiter and stoi would be enough for the conversion:
From the C++ reference for getline with delimiter:
Extracts characters from is and stores them into str until the delimitation character delim is found.
With this in mind, the code example below assumes the input is well-formed:
Example
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
vector<int> parseInts(const string& str, const char delim = ',')
{
vector<int> parsed;
stringstream ss(str);
string s;
while (getline(ss, s, delim)) // <- stores input in s upon hitting delimiter
parsed.push_back(stoi(s)); // <-- convert string to int and add it to parsed
return parsed;
}
int main()
{
string str = "3,12,36"; // <-- change to cin if you'd like
vector<int> ints = parseInts(str);
for (auto& i : ints)
cout << i << "\n";
}
Output
3
12
36
See more: getline, stoi

How to iterate over the words of a sentence in C++?

My input is "Hello World" and my targeted output is "olleH dlroW".
So my idea is to get the sentence into a variable and then loop over the words in the sentence, reverse each of them and finally concatenate them into a new variable.
My question is: how to iterate over the words of the sentence?
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
string reverseword(string word)
{
string rword;
int size = word.length();
while (size >= 0)
{
rword+= word[size];
size = size -1;
}
return rword;
}
int main()
{
string sentence;
cout<<"Enter the word/sentence to be reversed: ";
cin >> sentence;
string rsentence;
// for every word in the sentence do
{
rword = reverseword(word);
rsentence = rsentence + " " + rword;
}
cout<<rword;
return 0;
}
Before you can iterate over words in a sentence, you need to read a sentence from input. This line
cin >> sentence;
reads the first word of a sentence, not the whole sentence. Use getline instead:
std::getline(std::cin, sentence);
With sentence in memory, you can iterate it word-by-word using istream_iterator as follows:
stringstream ss(sentence);
for (auto w = istream_iterator<string>(ss) ; w != istream_iterator<string>() ; w++) {
string &word = *w;
...
}
Demo.
Here is a solution that uses find and reverse to achieve the output:
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string sentence;
std::getline(std::cin, sentence);
std::cout << sentence << std::endl;
size_t cpos = 0;
size_t npos = 0;
while((npos = sentence.find(' ', cpos)) != std::string::npos)
{
std::reverse(sentence.begin() + cpos, sentence.begin() + npos);
cpos = npos + 1;
}
std::reverse(sentence.begin() + cpos, sentence.end());
std::cout << sentence << std::endl;
return 0;
}
Input:
this is a nice day
Output:
this is a nice day
siht si a ecin yad
for(short i=0;i<sentence.length();i++){
if(sentence[i] == ' '){
counter++;
i++;
}
words[counter] += sentence[i];
}
Note the above loop to split the sentence with space and store it to a string array, words[]
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
string reverseword(string word) // function to reverse a word
{
string rword;
int size = word.length();
while (size >= 0)
{
rword+= word[size];
size = size -1;
}
return rword;
}
int main()
{
string sentence;
cout << "Enter the word/sentence to be reversed: ";
std::getline(std::cin, sentence);
string rsentence;
string words[100];
string rword;
short counter = 0;
for(short i=0; i<sentence.length(); i++){ // looping till ' ' and adding each word to string array words
if(sentence[i] == ' '){
counter++;
i++;
}
words[counter] += sentence[i];
}
for(int i = 0; i <= counter; i++) // calling reverse function for each words
{
rword = reverseword(words[i]);
rsentence = rsentence + " " + rword; // concatenating reversed words
}
cout << rsentence; // show reversed word
return 0;
}
I have corrected the code. Hope this helps...!!
NB : You were using cin to read space seperated string that is not possible. You must use std::getline(std::cin, sentence) to read space separated strings.
You can also use std::reverse() to reverse a string
Please refer to Most elegant way to split a string?
to split your sentence into tokens(words)
then, iterate over the new list of words to perform any operation
An answers above gives a way to convert your input to words, i.e., cin >> sentence returns a "word" (so, just call it repeatedly).
However, this brings up the question of what is a "word". You would like to translate a computer construct - string of characters - into a more complex form - words. So, you must define what you mean when you want words. It can be as simple as "space" separated substrings or your string - then use the split function, or read your string a word at a time (cin >> word)
Or you may have more stringent requirements, like they can't include punctuation (like a period at the end of a sentence) or numbers. Then think about using Regex and word patterns (like, "\w+").
Or you may want "real" words like you would find in a dictionary. Then you need to take into account your locale, parse your input into chunks (using split, Regex, or something), and look up each chunk in a human language dictionary.
In other words, "word" parsing is only as simple or complex as your requirements are.
With Boost you could use the boost::split function:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <boost/algorithm/string.hpp>
int main()
{
std::string sentence = "Hello world";
std::vector<std::string> words;
boost::split(words, sentence, boost::is_any_of(" "));
std::string rsentence;
for (std::string word : words) // Iterate by value to keep the original data.
{
std::reverse(word.begin(), word.end());
rsentence += word + " "; // Add the separator again.
}
boost::trim(rsentence); // Remove the last space.
std::cout << rsentence << std::endl;
return 0;
}
This answer is my humble contribution to the fight against global warming.
#include <string>
#include <iostream>
#include <algorithm>
#include <cctype>
int main()
{
std::string sentence;
while (std::getline(std::cin, sentence))
{
auto ws = sentence.begin();
while (ws != sentence.end())
{
while (std::isspace(*ws)) ++ws;
auto we = ws;
while (we != sentence.end() && !std::isspace(*we)) ++we;
std::reverse(ws, we);
ws = we;
}
std::cout << sentence << "\n";
}
}
This assumes "word" is defined as "a sequence of non-whitespace characters". It is easy to substitute a different character class instead of "non-whitespace", e.g. for alphanumeric characters use std::isalnum. A definition that reflects the real-world notion of word as e.g. used in natural language sciences is far far beyond the scope of this answer.

Changing string to capital letters function

I'm dealing with some excercise, according to which I have to change string given on the input to the same string, written with capital letters.
Here's is my try, for some strange reason it prints out only the first word of string, it doesn't read the bit that is after space...
Any ideas how to fix it ?
#include <iostream>
#include <string>
using namespace std;
void uppercase(string str)
{
locale loc;
for(size_t i=0; i<str.length(); ++i)
{
cout << toupper(str[i], loc);
}
}
int main(void)
{
string text;
cout << "Input text, please: " << endl;
cin >> text;
uppercase(text);
}
I know that there might be different ways to solve this excersice, but I would like to stick with my method. Any potential mistakes ?
Sure, use std::getline to get a whole line instead of one word. You should almost always use it, actually, because line-oriented is the way most programs take input.
Reading from std::cin is space-delimited. In order to get the whole string up to a new-line, you want std::getline.
std::getline( std::cin, text);
void uppercase(string str)
{
locale loc;
for(size_t i=0; i<str.length(); ++i)
{
if(str[i] != " ")
{
cout << toupper(str[i], loc);
}
}
}

Read a file of strings with quotes and commas into string array

Let's say I have a file of names such as:
"erica","bosley","bob","david","janice"
That is, quotes around each name, each name separated by a comma with no space in between.
I want to read these into an array of strings, but can't seem to find the ignore/get/getline/whatever combo to work. I imagine this is a common problem but I'm trying to get better at file I/O and don't know much yet. Here's a basic version that just reads in the entire file as one string (NOT what I want, obviously):
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
fstream iFile("names.txt", ios::in);
string names[5];
int index = 0;
while(iFile)
{
iFile >> names[index];
index++;
}
for(int i = 0; i < 5; i++)
{
cout << "names[" << i << "]: " << names[i] << endl;
}
Output:
names[0]: "erica","bosley","bob","david","janice"
names[1]:
names[2]:
names[3]:
names[4]:
Also, I understand why it all gets read as a single string, but then why are the remaining elements not filled with garbage?
To be clear, I want the output to look like:
names[0]: erica
names[1]: bosley
names[2]: bob
names[3]: david
names[4]: janice
The easiest way to handle this:
Read the entire file and place it into a string, Here is an example of how to do it.
Split the string that you got from number 1. Here is an example of how to do that.
Stream extraction delimits by a space. Therefore the entire file gets read as one string. What you want instead is to split the string by commas.
#include <iostream>
#include <fstream>
#include <algorithm>
#include <sstream>
fstream iFile("names.txt", ios::in);
string file;
iFile >> file;
std::istringstream ss(file);
std::string token;
std::vector<std::string> names;
while(std::getline(ss, token, ',')) {
names.push_back(token);
}
To remove the quotes, use this code:
for (unsigned int i = 0; i < names.size(); i++) {
auto it = std::remove_if(names[i].begin(), names[i].end(), [&] (char c) { return c == '"'; });
names[i] = std::string(names[i].begin(), it);
}
remove_if returns the end iterator for the transformed string, which is why you construct the new string with (s.begin(), it).
Then output it:
for (unsigned int i = 0; i < names.size(); i++) {
std::cout << "names["<<i<<"]: " << names[i] << std::endl;
}
Live Example

How to convert a sentence from upper case to lower case that contains space and numbers

I'm trying to convert a sentence from upper case to lowercase. I also write a code but I stopper when a space is appear. How can I fix this problem and convert the whole sentence? Here is my code
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char str[100];
cin>>str;
for(int i=0;i<strlen(str);i++)
{
if(str[i]>='A'&&str[i]<='Z')
{
str[i]=str[i]+32;
}
}
cout<<str<<endl;
return 0;
}
It's because of theinput operator >>, it breaks on space. If you want to read a whole line then use std::getline to read into a std::string instead.
Then read about the C++ standard algorithms, like for example std::transform. Also, std::tolower doesn't modify anything that's not an upper-case letter, so it's a good function to use.
The error is because operator>> delimites on spaces. The alternative is to use getline. See the following example:
#include <cstring>
#include <iostream>
#include <string>
int main() {
std::string s;
std::getline(std::cin, s);
std::cout << "Original string: " << s << std::endl;
if (!std::cin.fail()) {
const int len = strlen(s.c_str());
for (size_t i = 0; len > i; ++i) {
if ((s[i] >= 'A') && (s[i] <= 'Z'))
s[i] = s[i] - 'A' + 'a';
}
}
std::cout << "New string: " << s << std::endl;
return 0;
}
The reason input stops at whitespace is because formatted input is delimited by whitespace characters (among others). You will need unformatted I/O in order to extract the entire string into str. One way to do this is to use std::istream::getline:
std::cin.getline(str, 100, '\n');
It's also useful to check if the input succeeded by using gcount:
if (std::cin.getline(str, 100, '\n') && std::cin.gcount())
{
...
}
But in practice it's recommended that you use the standard string object std::string which holds a dynamic buffer. To extract the entire input you use std::getline:
std::string str;
if (std::getline(std::cin, str)
{
...
}
Here is one of the examples of doing it using transform function.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string str;
if (getline(cin, str))
{
transform(str.begin(), str.end(), str.begin(), ptr_fun<int, int>(toupper));
}
cout << str << endl;
return 0;
}