I have this simple program that basically accepts user input and outputs it to the screen. This program works fine when I input an integer. However, when I input a string literal, this negative integer is obtained as the output. (-858993460), regardless of any string input size.
I am currently using Visual Studio 2015 Community Edition, if that matters.
Here is my code.
#include "stdafx.h"
#include <iostream>
#include <string>
int main() {
int a;
std::string b;
b = "Type something";
std::cout << b << std::endl;
std::cin >> a;
std::cout << "You said " << a << std::endl;
}
I have tried searching but to no avail. Hence, I have two questions.
1) Why is it outputting this particular negative integer when I gave it a string input?
2) Why didn't the program give me a compilation error, syntax error, or a crash? Instead, why did it go on outputting that integer?
Sorry for my bad English.
1) Why is it outputting this particular negative integer when I gave it a string input?
Because your integer was not initialized to anything, it's outputting whatever is there (primitives like int do not get default values when declared at function-level scope). Reading of the integer from the stream failed because you provided a string literal, so the integer value was not changed. If you initialize the value of the integer to 42 you'll see that it's value was unchanged when it gets printed (until C++11. After C++11 the value will become 0).
2) Why didn't the program give me a compilation error, syntax error, or a crash? Instead, why did it go on outputting that integer?
streams force the programmer to check what happened (in general*). They have implicit conversions to booleans so you can conveniently check if anything went wrong.
Try to augment your code like so:
std::cin >> a;
if (!std::cin)
{
std::cerr << "Failed to read!" << std::endl;
exit(1);
}
Demo1
*If you want std::cin to throw an exception on failure, then you can use basic_ios::exceptions to do so:
std::cin.exceptions(std::istream::badbit | std::istream::failbit);
Demo2
There is already an excellent answer. I just want to add for the second question
2) Why didn't the program give me a compilation error, syntax error,
or a crash? Instead, why did it go on outputting that integer?
error?
The compiler cannot know what the user will write. It could it could be something that can be streamed to an int but it also could be that it cannot. Thus the compiler has no chance to issue a warning/error in this situation.
crash?
If this code would cause a crash then it would be impossible to use cin to write code that cannot be crashed by malformed user input. That would make cin rather useless.
conclusion?
It is your responsibility to check if the input operation went ok and to react accordingly if it didnt.
You're storing user input in an int.
I suggest you convert the input string to int as in
std::cin >> atoi(a);
Related
I need to create a program that reads in a list of random integers via input redirection and performs various tasks with them. For the purpose of this question I just want to print the sum of each number + 1. Trouble is, I don’t know how to get it to perform the operation on anything but the first number in the list. My mini program (program.cpp) is
#include <iostream>
using namespace std;
int main () {
int input;
bool arb = true;
cin >> input;
while (arb) {
cout << input + 1 << endl;
}
return 0;
}
and a sample textfile (textfile.txt) I'm using contains
9
8
7
6
When I run it it prints out “10” for infinity. What I’d like it do is print out
10
9
8
7
or the equivalent for whatever other text file may be used.
I thought maybe I could somehow reference specific lines in the textfile, but from searching how to do that all the similar questions I could find seemed to have solutions that required fstream, which is something I haven’t learned yet and therefore I’m not allowed to use it (this is for a class assignment).
The only compiler directives I’ve learned are iostream, string, cmath, iomanip, cstdlib, and ctime. The ways to get input I’ve learned are cin >> input, cin.get(input), and cin.getline(input), so if there are other ways of reading in the file besides those 3 that I’m unaware of, unfortunately I can’t use it. Note that my program HAS to use a while loop. The way the program will be run is
./program < whatevertextfile.txt
which I can't change.
given these restrictions, how can I get my program to read in and use each integer in the text file?
The idiomatic way to read a sequence of white-space separated integers in C++ would be
#include <iostream>
using namespace std;
int main () {
int input;
while (cin >> input) {
cout << input + 1 << endl;
}
return 0;
}
Let's come to why this works the way it does.
cin >> input
discards possible white-space and then reads an integer from the standard input. Moreover, it returns a reference of the cin object used. With this returned reference, you can call the bool conversion operator to check if any of the fail bits is set in the given std::basic_ios object. So
while (cin >> input)
does two things. Read an integer from standard input and check if it successfully completed the operation. As long as this operation succeeds, your while loop continues to iterate and you print the numbers.
See http://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt for reference on std::basic_istream::operator>>.
See http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool for reference on operator bool.
Edit1: Move references to bottom so that the answer is more readable.
This question already has answers here:
Why does stringstream >> change value of target on failure?
(2 answers)
Closed 7 years ago.
I am completely new to C++ and am trying to write an extremely basic program, but I am having issues with initializing an integer. I have stripped it down to a very small program that still has the issue:
#include <iostream>
using namespace std;
int main()
{
cout << "Please enter your age\n";
int age = -1;
cin >> age;
cout <<"\n\n Your age is " << age << "\n\n";
}
I read that if I attempt to input a string, e.g. abc to the age variable, then the input should fail and the value should be left alone and therefore it should print Your age is -1.
However, when I run this program and type abc, then it prints Your age is 0. Why?
The behavior you want to observe changed in 2011. Until then:
If extraction fails (e.g. if a letter was entered where a digit is expected), value is left unmodified and failbit is set.
But since C++11:
If extraction fails, zero is written to value and failbit is set. [...]
(From cppr.)
With the compiler I tested against (gcc 4.8.4), the value is set to zero (for the 'abc' input) regardless of which version of the standard I compile against. Note also that it is set to minimum/maximum values if you provide a valid integer that is outside of the supported range of the variable that you are assigning to.
A more important point though, is that ignoring error flags is a recipe for disaster. Once you have an error in the input, any subsequent input is suspect (without hacks like ignore()). Situations like this are a good candidate for using exception handling.
Here's how I might implement what you are trying to do (but, again, considering the case of multiple inputs, recovering from errors is a messy business):
cin.exceptions( ~std::ios::goodbit );
try { cin >> age; }
catch ( std::ios::failure const & )
{
age=-1;
cin.clear();
cin.ignore(999,'\n');
}
or without exeptions:
cin >> age;
if ( cin.fail() ) age=-1, cin.clear(), cin.ignore(999,'\n');
See here for similar questions:
Why does stringstream >> change value of target on failure?
istream behavior change in C++ upon failure
Here are up-to-date docs for the operator in question:
http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
http://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt
I'm using positional notation method convert binary to decimal and its different i guess nobody has tried it yet i guess, and in this I'm using for_each loop
Here are some steps:
store binary as string
-take out one digit at a time from string using for_each loop and do operation.
int main(void)
{
string input;
cout << "Enter string of binary digits " ;
cin >> input ;
for_each(input.begin(), input.end(),bitodec);
cout << "Decimal equivalent is " << u << endl;
system("PAUSE");
}
here is full code
There is logical error.
I am not sure what exactly it is you are asking, since you did not state a question. I presume, however, that you would like to know why you get the compiler error:
prog.cpp:13:48: error: ‘for_each’ was not declared in this scope
for_each(input.begin(), input.end(),bitodec);
(It would have been nice if this was included in the question)
You get this error because you try to use std::for_each, which was not declared in your program. It is defined in the "algorithm" header, so to fix this problem, you would have to add
#include <algorithm>
somewhere at the beginning of your file.
There are, however, some other problems with the complete code(which should really have been included in your question), for instance: Your global variable u is never modified, because you declare a new, temporary one in bitodec's if block and modify this one.
So, as Joachim Pileborg mentioned in the comments, it would be much easier(and apparently less error prone), to simply use std::stoi.
I hope this helps ;-)
As the documentation of std::bitset says:
Bitsets can be manipulated by standard logic operators and converted to and from strings and integers.
So using std::bitset is a simple way to achieve your goal. For example:
std::string bit_string = "110010";
std::bitset<8> b3(bit_string); // [0,0,1,1,0,0,1,0]
std::bitset<8> b4(bit_string, 2); // [0,0,0,0,0,0,1,0]
std::bitset<8> b5(bit_string, 2, 3); // [0,0,0,0,0,0,0,1]
I've got this code with use of cin.peek() method. I noticed strange behaviour, when input to program looks like qwertyu$[Enter] everything works fine, but when it looks like qwerty[Enter]$ it works only when I type double dollar sign qwerty[Enter]$$. On the other hand when I use cin.get(char) everything works also fine.
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
char ch;
int count = 0;
while ( cin.peek() != '$' )
{
cin >> ch; //cin.get(ch);
count++;
}
cout << count << " liter(a/y)\n";
system("pause");
return 0;
}
//Input:
// qwerty$<Enter> It's ok
//////////////////////////
//qwerty<Enter>
//$ Doesn't work
/////////////////////////////
//qwerty<Enter>
//$$ works(?)
It's because your program won't get input from the console until the user presses the ENTER key (and then it won't see anything typed on the next line until ENTER is pressed again, and so on). This is normal behavior, there's nothing you can do about it. If you want more control, create a UI.
Honestly I don't think the currently accepted answer is that good.
Hmm looking at it again I think since, operator<< is a formatted input command, and get() a plain binary, the formatted version could be waiting for more input than one character to do some formatting magic.
I presume it is way more complicated than get() if you look what it can do. I think >> will hang until it is absolutely sure it read a char according to all the flags set, and then will return. Hence it can wait for more input than just one character. For example you can specify skipws.
It clearly would need to peek into more than once character of input to get a char from \t\t\t test.
I think get() is unaffected by such flags and will just extract a character from a string, that is why it is easier for get() to behave in non-blocking fashion.
The reason why consider the currently accepted answer wrong is because it states that the program will not get any input until [enter] or some other flush-like thing. In my opinion this is obviously not the case since get() version works. Why would it, if it did not get the input?
It probably still can block due to buffering, but I think it far less likely, and it is not the case in your example.
I'm having a annoying problem with a C++ function that I wrote and whose purpose is to validate de user input. The function reads the user input, verifies if it's a number and, if so, if it is in the range [min, max].
The problem occurs when I invoke the template function with a unsigned type, like size_t, and the input is a negative number. The string stream converts the string to something like 4294967291. I can see that the program is converting the data to a value near de maximum value of the unsigned data type (defined in the numeric_limits header) but my question is why, since the if statement should stop at sstream >> value?
My code:
template <class T>
T getNumberInput(std::string prompt, T min, T max) {
std::string input;
T value;
while (true) {
try {
std::cout << prompt;
std::cin.clear();
std::getline(std::cin, input);
std::stringstream sstream(input);
if (input.empty()) {
throw EmptyInput<std::string>(input);
} else if (sstream >> value && value >= min && value <= max) {
std::cout << std::endl;
return value;
} else {
throw InvalidInput<std::string>(input);
}
} catch (EmptyInput<std::string> & emptyInput) {
std::cout << "O campo não pode ser vazio!\n" << std::endl;
} catch (InvalidInput<std::string> & invalidInput){
std::cout << "Tipo de dados inválido!\n" << std::endl;
}
}
}
Thank you for your time!
In C++ arithmetic involving an unsigned type with n value bits, is guaranteed to be modulo 2^n. That means any result is wrapped back into the range 0 through 2^n-1, by adding or subtracting a suitable multiple of 2^n. This is so also in C.
So you need to check the input for minus sign, or add some other check.
By the way, your if with >> and && produced some effect on my bad-code-meter. I can never remember the operator precedences for >> versus &&. I guess if it compiled it must be OK, though, since >> can't take a value right-hand-side. Checking... OK, but I'd use parentheses to clarify that.
Also, on the code structure, it would be a good idea to separate the interactive input thing from the checking of the input. E.g., can you use any of that code in a GUI program, with input from an edit field? No, not as it is...
Cheers & hth.,
Alf has already answered this, but I had a couple of other thoughts.
Pull the code that gets the input out of the try block. You're not catching any exceptions that it might throw, so it doesn't communicate the intent as well. The try block should start right before the if (input.empty())...
Then pull all of the stuff in the try block into a single validate function. This cleans up the code here. For use in a GUI, though, you would want to create a function that just gets the input without validation and expose the validation function. Then the user could handle the validation exceptions as needed. Although in this case, I don't see an advantage to using exceptions as opposed to simple error codes for the validation.
Hope this helps,