I wanted to grab a 10 character and store it in cstring and ignore the rest but I have having problem with it. The program doesn't halt for input the next time. How can I make it so that it halts and lets me enter again.
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
char arr[11] = " "; //This is a cstring
string x; //will test with this variable
cout <<"Enter 10 character, rest will be ignored: \n";
cin.getline(arr, 10,'\n');
cin.ignore();
cout <<"Testing..\n";
cin >>x; //Should make the program halt
cout <<arr <<endl;
cout <<x;
}
cin.getline(arr, 10,'\n') will output at most 9 characters, not 10 characters, stopping if a line break is read before reaching 9 characters. If you want to receive 10 characters, you need to set the count parameter to 11 - the full size of arr - to include room for 10 characters + the null terminator.
Calling cin.ignore() afterwards without any parameters will ignore only 1 character. So, if the user types in more than count+1 characters, you are not ignoring them all. You should tell cin.ignore() to ignore all characters up to the next line break, if no line break was reached during the read.
Try this instead:
#include <iostream>
#include <string>
#include <limits>
using namespace std;
int main()
{
char arr[11]; //This is a cstring
string x; //will test with this variable
cout << "Enter 10 character, rest will be ignored: \n";
if (cin.getline(arr, 11, '\n'))
{
// <= 10 characters w/ line break were read
}
else
{
if (cin.fail() && !cin.bad()) // exactly 10 characters w/o a line break were read, ignore the rest...
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
cout << "Testing..\n";
cin >> x; //Should make the program halt
cout << arr << endl;
cout << x;
}
That being said, this is C++, not C. It would be easier to use std::getline() instead, eg:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str; //This is a c++ string
string x; //will test with this variable
cout << "Enter 10 character, rest will be ignored: \n";
getline(cin, str);
if (str.size() > 10)
str.resize(10);
cout << "Testing..\n";
cin >> x; //Should make the program halt
cout << str << endl;
cout << x;
}
Related
The first character of cstring keeps being removed upon the second execution of getline in ifstream:
#include <iostream>
#include <fstream>
using namespace std;
int main(){
char input[102];
ifstream keyTextFile("key.txt");
while (keyTextFile.getline(input, 102, '\n')) {
cout << input[0] << input[1] << endl;
cout << input << endl;
}
cout << input[0] << input[1] << endl;
keyTextFile.close();
return 0;
}
Currently, key.txt is one line:
0x0ffa331cc8765ddd
The code outputs:
0x
0x0ffa331cc8765ddd
x
The debugger shows input[0] changing from '0' to '\0' on the second execution of getline. How can I avoid this while allowing getline to scan a potentially large document?
please keep the answer to c-string implementation.
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;
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
I need to be able to enter a sentence and have it spit back out. However, if a number is entered in the sentence, it should be output along with the words but it must be doubled.
I've tried implementing an if statement into my code to see if I could check if a number was entered, and if so print out that value in the stream *2, however this doesn't work because if I enter a number first then some text it breaks, if I don't enter the number as the second value of the sentence than it only prints the first word entered.
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream>
using namespace std;
int main()
{
string sentence;
string word;
float val=0;
cout<<"Enter a sentence: ";
getline(cin, sentence);
stringstream ss;
ss.str(sentence);
while (ss >> word || ss >> val)
{
if (ss >> val)
{
cout << val * 2;
}
else
{
cout << word << endl;
}
}
return 0;
}
If I enter a sentence like "I walked 2 times today" then it should output it as:
I
walked
4
times today
But this would only be output as:
I
Solved the issue, had to use ss.eof() method to go to the end of the StreamString and stop and if a value that was entered into the string was a number, it would be printed out. My program was stopping when a certain if statement was met.
Here is my code for a basic copycat program that just copys whatever the user types:
#include <iostream>
using namespace std;
#include <string>
int main()
{
cout << "type something.. I dare you..." << endl;
for (;;)
{
string usrin;
cout << "You: ";
cin >> usrin;
cout << "Me: " << usrin;
}
return 0;
}
But when the user inputs more than one word i get this:
Me: more
You: than
You: Me: one
You: Me: word
You:
any and all help is appreciated! thank you!
You need to use cin.getline(usrin) instead of cin >> usrin.
cin >> usrin stops reading when it finds whitespace characters in the stream but leaves the rest of the stream for the next time cin is used.
cin.getline will read until the end of the line. However, you will need to change usrin to an array of char.
char usrln[MAX_LINE_LENGTH];
where MAX_LINE_LENGTH is a constant that is bigger than the length of the longest line you expect to see.
After each input, \n leaved behind in input buffer and read on next iteration. You need to flush your input buffer. Use
cin.ignore(MAX_INT, '\n'); //Ignores to the end of line
Add <limits.h> header.
#include <iostream>
#include <limits.h>
#include <string>
using namespace std;
int main()
{
cout << "type something.. I dare you..." << endl;
for (;;)
{
string usrin;
cout << "You: ";
cin >> usrin;
cout << "Me: " << usrin ;//<<endl;
cin.ignore(INT_MAX, '\n');
}
return 0;
}