Taking input of strings with white spaces - c++

I am trying to input strings which may contain white spaces.The entire string can be made of white spaces.
Here is what I am doing-
#include <bits/stdc++.h>
using namespace std;
char arr[1000][1000];
int main()
{
int t,m=3,n=2;
cin >> t;
while(t--)
{
string str;
for(int i=0;i<m;i++)
{
getline(cin,str);
cout << str[0] << endl;
}
return 0;
}
}
Here t is no of test cases.
Say for m=3, I have this input-
1
#T
--
--
For visibility, - is used to represent white spaces.In actual input,there are white spaces instead of - .
This is the output I get-
NUL
#
-
Another thing which I tried is this-
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
cin >> arr[i][j];
}
where m=3,n=2 for the example above.But printing this arr gives me following output-
#T
NULNUL
NULNUL
I am not sure why I am getting this output.Why am I getting NUL instead of white spaces.Also in the first code, the output I get is NUL before # ,why is that?

There's no need to write such a complicated code to obtain whitespaces from cin. You can just take an advantage of std::noskipws flag.
Solution 1:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
char x;
for (int i=0; i<10; i++)
{
cin >> noskipws >> x;
str += x;
}
cout << str;
}
Live demo
Solution 2:
or even simpler, without any string:
#include <iostream>
using namespace std;
int main()
{
char str[10];
cin.read(str, sizeof(str));
cout << str;
}
Live demo
Solution 3:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
getline(cin, str);
cout << str;
}
Live demo

You are printing str[0] - this is not a string, this is a single character. When your string is empty, the only thing it contains is null-terminator ('\0'). And when you access the first element of your string with [], you are accessing this null-terminator. And since you are printing it as a character, you see NUL as your output.

Related

How would I split up user input into a char and an integer?

I am working on a project where I have to parse data from user input.
#include <iostream> // for cin and cout
#include <iomanip> // for setw()
#include <cctype> // for toupper()
using namespace std;
int main(){
string playerInput;
cin >> playerInput;
//Player would input strings like C13,C 6, I1, Z 16, etc...
}
return 0;
I've tried something like this, which kinda works but only if the letter proceeds the number in the string.
int myNr = std::stoi(playerInput);
What my end goal is to grab the letter and number from the string, and place them in a char variable and a integer variable respectively. I am stuck on how to proceed from here and could use some help, thanks!
This is the simplest and the shortest way to achieve that (it also ignores spaces and tabs):
int main() {
char ch;
int n;
cin >> ch >> n;
cout << "ch = " << ch << ", n = " << n << endl;
}
I think that other answers are a bit overcomplicated.
You could do like what you had:
char letter = playerInput.front();
playerInput.erase(0);
int number = std::stoi(playerInput);
Of course, that doesn't allow for spaces. Removing spaces can be quite tedious, but it could be done like:
playerInput.erase(
std::remove_if(
begin(playerInput), end(playerInput),
[](uint8_t ch) { return std::isspace(ch); }),
end(playerInput));
Full Demo
Live On Coliru
#include <cctype> // for toupper()
#include <iomanip> // for setw()
#include <iostream> // for cin and cout
#include <algorithm> // for remove_if
static bool ignorable(uint8_t ch) {
return std::isspace(ch)
|| std::ispunct(ch);
}
int main() {
std::string playerInput;
while (getline(std::cin, playerInput)) {
playerInput.erase(
std::remove_if(
begin(playerInput), end(playerInput),
ignorable),
end(playerInput));
if (playerInput.empty())
continue;
char letter = playerInput.front();
playerInput.erase(begin(playerInput));
int number = std::stoi(playerInput);
std::cout << "Got: " << letter << " with " << number << "\n";
}
}
Prints
Got: C with 13
Got: C with 6
Got: I with 1
Got: Z with 16
You have the right idea in using std::stoi. My code expands your approach:
string playerInput;
getline(cin, playerInput);
char c1 = playerInput[0];
int num = stoi(playerInput.substr(1));
The above code receives an input string, then takes out the first character and uses std::stoi on the rest of the string.
Note that I use std::getline to account for the possibility of there being spaces in the input. If you are doing this repeatedly, you will need to add cin.ignore() after each getline() statement. See this link for more info.
std::cin stops reading input when it encounters a space. You can use std::getline() if your input has spaces. To parse your string, you should check out std::stringstream. It allows you to read from a string as if it were a stream like std::cin.
#include <iostream> // for cin and cout
#include <iomanip> // for setw()
#include <cctype> // for toupper()
#include <sstream>
int main(){
std::string playerInput;
int i;
char c;
std::getline(std::cin, playerInput); // Remove trailing newline
std::getline(std::cin, playerInput);
//Player would input strings like C13,C 6, I1, Z 16, etc...
//String Stream
std::stringstream playerInputStream(playerInput);
//Read as if you were reading through cin
playerInputStream >> c; //
playerInputStream >> i;
}
return 0;

How to get string input n times? [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 3 years ago.
I have a C++ program. I want to get a number from the user (t) and force the user to enter line t times but the program's execution terminates after 1 iteration. This is the code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
int t;
cin >> t;
for (int i=0; i< t; i++) {
getline(cin, str);
cout << str;
}
return 0;
}
Can anyone explain me why this happening and how to solve it?
Thank you my friends.
The newline character is still in the buffer when you do cin >> t so the next line you read will be blank. When you mix formatted input (>>) and unformatted (std::getline) you often get in situations like this and you need to take measures when switching to unformatted input. Example remedy:
#include <iostream>
#include <limits>
#include <string>
using namespace std;
int main() {
string str;
int t;
cin >> t;
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // skip the rest of the line
for(int i = 0; i < t; i++) {
if(getline(cin, str)) // check that the getline actually succeeded
cout << str << '\n';
else
break;
}
return 0;
}
When you enter your first character (the times to repeat), a character is left in the cin buffer - newlines are not consumed by cin >>. As a result, getline(cin, str) reads this character and takes it as the first input, which then empties the buffer out and lets you enter the others.
You can clear the buffer with std::cin.ignore(1); to remove that trailing character - this lets your code run as anticipated. Why not just use cin >> str, though? That solves the problem and avoids a call to getline.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
int t;
cin >> t;
//clear one character out of buffer
cin.ignore(1);
//note that 1 is used for demonstration purposes
//in development code, INT_MAX, numeric_limits<streamsize>::max(),
//or some other large number would be best, followed
//by std::cin.clear()
for (int i=0; i< t; i++) {
cout << "input: ";
//you could use cin >> str; instead of getline(cin, str);
getline(cin, str);
cout << "got: " << str << std::endl;
}
return 0;
}
Demo

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

C++ Using std::getline in place of cin >>

In a problem were i have to take n number of strings as input and count the ones containing a given substring(case insensitive).
Here's my code:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include<string>
using namespace std;
int main()
{
std::string str2 = "hello";
std::string str3 = "HELLO";
short int n,count=0,i;
cin>>n;
std::string str1[n];
for(i=0;i<n;i++)
{
std::getline(std::cin,str1[i]); //here getline is taking only n-1 inputs
std::size_t found1=str1[i].find(str2);
std::size_t found2=str1[i].find(str3);
if(found1!=std::string::npos || found2!=std::string::npos)
count++;
}
cout<<count;
return 0;
}
Since i cant use cin as string includes spaces or cin.getline() as have to use string type in place of char[].
Problem with my code is std::getline() is only taking n-1 inputs.Cant figure out why?
The first getline after cin reads the remainder of the line, which is probably empty. This is why when reading user input, it is usually better to use getline and process input using code.
After cin >> n the input stream is positioned just after the number n. You can use a getline just to read the newline and then throw it away to position to the start of the next line.
This code should work
#include <iostream>
#include <string>
using namespace std;
int main() {
int n = 0, count = 0;
cin >> n;
do {
string str;
getline(cin, str);
if (str.find("HELLO") != string::npos || str.find("hello") != string::npos) {
count++;
}
} while (n-- && n >= 0);
cout << count << endl;
return 0;
}

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