How is C++ supposed to print negative values in base 8 or 16? I know I can try what my current compiler/library does (it prints the bit pattern, without a minus in front) but I want to know what is should do, preferrably with a reference.
It seems that none of the standard output facilities support signed formatting for non-decimals. So, try the following workaround:
struct signprint
{
int n;
signprint(int m) : n(m) { }
};
std::ostream & operator<<(std::ostream & o, const signprint & s)
{
if (s.n < 0) return o << "-" << -s.n;
return o << s.n;
}
std::cout << std::hex << signprint(-50) << std::endl;
You can insert an 0x in the appropriate location if you like.
From §22.2.2.2.2 (yes, really) of n1905, using ios_base::hex is equivalent to the stdio format specifier %x or %X.
From §7.21.6.1 of n1570, the %x specifier interprets its argument as an unsigned integer.
(Yes, I realize that those are wacky choices for standards documents. I'm sure you can find the text in your favorite copy if you look hard enough.)
Related
I want to read unsigned integers in base-10 (decimal) representation from a C++ iostream with at least rudimentary error detection. In my view, minus signs would clearly be an error in this case, because unsigned integers have no sign. However, the gcc is of a different opinion:
#include <iostream>
#include <sstream>
int main() {
std::stringstream a("5"), b("-0"), c("-4");
unsigned int i;
a >> i; if ( a ) std::cout << i << std::endl; else std::cout << "Conversion failure" << std::endl;
b >> i; if ( b ) std::cout << i << std::endl; else std::cout << "Conversion failure" << std::endl;
c >> i; if ( c ) std::cout << i << std::endl; else std::cout << "Conversion failure" << std::endl;
return 0;
}
gives me an output of
4294967292
for the last line, as if a signed integer -4 had been read and converted to unsigned int.
Apparently, the GCC people see this as a feature. Is there some standard that mandates this behaviour, and is there any way short of writing an own parser to get out of it, i.e. detect "-4" (and maybe "-0") as conversion errors?
Consulting C++03, 22.2.2.1.2/11, the formats are inherited from scanf and friends, which in turn all say that the converted character sequence is "optionally signed", even for the ones with unsigned output. strtoul is the same.
So, I suppose you could say the standard that mandates the behavior is C89 for C++03, C99 for C++11.
Since the - happens to be allowed only as the first character, I suppose that the workaround is to check for it with peek before using operator>>.
If I read 22.2.2.1.2/table 5 correctly it shows that extracting into an unsigned is equivalent to scanf with %u which appears to also do the negative -> positive conversion.
Would it be really different if you'd done this?
int i;
unsigned int u;
c >> i;
u = i;
std :: cout << u;
It doesn't matter so much that operator>> tolerates the sign mismatch because the underlying C rules will allow a silent conversion in any case. You're not fundamentally adding any safety by "strengthening" the input operator.
That said, my gcc (4.3.5 on Solaris) says it's a conversion error.
#include <iostream>
using namespace std;
int main()
{
int *a = nullptr;
int b;
a = &b;
cout << noshowbase;
cin >> b;
cout << dec << a << '\t' << oct << a << '\t' << hex << a;
}
Consider this code.. It is designed to convert a variable's (here b) address (&b or a) which is a hex integer to dec and oct values using <iostream> stream manipulators.. But on running, the output is same for all of them(hex,dec,oct).. Neither, there is any compilation error. So can you please elaborate the reason for this?? Also the noshowbase does not seems to be having any effect on output.. 0x is output anyways before the address..
An address is not a hex integer. It's an address.
It just so happens that an address is implemented as an integer, referring to a memory location, and can be reinterpreted as an integer. This is rarely a useful thing to do (particularly if you are a fan of bug-free code), but it comes up now and again. You can use reinterpret_cast<uintptr_t>(a) to do that. (Note that converting to int will not, in general, work properly. Remember what I said about bug-free code.) When you print the resultant integer, it will print as a decimal, octal, or hexadecimal integer, depending on the currently-set base.
To address your topic, there is no such thing as a "hex integer". There are integers and they can be formatted as hex, but the formatting is not an intrinsic part of the integer.
Now, why are pointers always formatted as hex? The reason is that that's the way it is defined to work. I'd also call this convenient, but that might be because I'm familiar with the format and can read some information from it even better than from decimal output. The reason this doesn't change with formatters is that a pointer is not considered an integer. You will also find that pointer arithmetic doesn't behave like integer arithmetic, which is a case where the core language behaves like IOstreams.
So, how to get the format of your choice? Simple, convert the pointer to an integer first, then you can use the formatting of your choice. In order to do that, I would use size_t i = reinterpret_cast<size_t>(&b);. Depending on the compiler, I would also consider using uintptr_t instead of size_t, because that one is explicitly intended to hold information from a pointer.
You can cast the pointer to unsigned long first:
unsigned long p = (unsigned long) a;
cout << "dec=" << dec << p << endl;
cout << "oct=" << oct << p << endl;
cout << "hex=" << hex << p << endl;
I was just writing some code to spit out a wave header. I started typing this:
file << 0x52 << 0x49 << 0x46 << 0x46 << ...
This made me think: How does a compiler tell the difference between interpreting the above as this:
file << 0x52; file << 0x49; file << 0x46; file << 0x46;
... and this:
file << (0x52 << 0x49 << 0x46 << 0x46);
And of course, all permutations/combinations of possibilities of these operators.
My guess is that the compiler somehow knows that the first is correct and the second is wrong, but what rules is it following?
Operators in C++ have a precedence and an associativity.
The expression
a << b << c << d
is interpreted (because << is left-associative) as
((a << b) << c) << d
so thanks to the fact that operator<< for a stream returns the stream itself you get the "chained output" look.
For example the assignment operator is instead right-associative, therefore
a = b = c = d
is interpreted as
a = (b = (c = d))
Note that about using << operator for streams there is a subtle fact that is often misunderstood by C++ novices. Precedence and associativity rules will only affect the result, but not the order in which the result is computed. For example in
std::cout << f() << g() << h();
it's possible that evaluation of h() happens before evaluation of g(). Even worse the idea of an evaluation order is misplaced for C++... because in
std::cout << f(g()) << h(i());
a valid sequence for the calls is also i, g, f, h.
Short answer: from the context.
Long answer: Writing a C++ compiler is a tough task, because C++ has a complex semantic.
First of all, if operator<< were not overloaded for fstreams, that statement would be invalid.
Moreover, we invoke operator<< that way due to ADL, otherwise it'd have been (that is valid too, of course)
std::operator<<(file, 0x52).operator<<(file, 0x49) [...]
Instead, if the left hand side were a builtin one, there would be no need to look into fstream for something like
friend std::ofstream& operator<<(std::ofstream&, int)*
*unsigned int could match as well
as the behavior of a left shift on a built in type (such as unsigned int) is well defined, while an user-defined type isn't.
In this case
file << (0x52 << 0x49 << 0x46 << 0x46);
the expression inside the parenthesis is interpreted before file <<, as it has an higher precedence than file <<.
I have assigned an integer to a double variable, but cout prints the double variable as an int. not as double . If I introduce cout << showpoint; in the code then I m able to see the decimal values at the out put . Why is it so in the first case ? Here is the code .
#include <iostream>
using namespace std;
template <class T>
T sum(T a,T b)
{
T retval;
retval=a+b;
return retval;
}
int main()
{
double a,x;
float y,v=4.66;
int z(3);
x=z;
y=(double)z;
a=sum(5,6);
//cout << showpoint;
cout<<"The value of a is : "<<a<<endl;
cout<<"The value of x is : "<<x<<endl;
cout<<"The value of y is : "<<y<<endl;
}
The output in first case is
The value of a is : 11
The value of x is : 3
The value of y is : 3
The output after enabling cout<<showpoint in the second case is
The value of a is : 11.0000
The value of x is : 3.00000
The value of y is : 3.00000
By default, floating point types are only displayed with a decimal point if they need one. If they have an integer value, they are displayed without one.
As you found, you can change this behaviour with showpoint (and change it back with noshowpoint), if you want.
The answer seems to be in the same link posted by you. Just that cpp standards (i mean std streams) have the printing of trailing zeros disabled by default.
The fundamental reason is only because that's what the standard
says. For historical reasons, C++ output formatting is defined
in terms of C and printf formatting. By default, floating
point is output using the %g format, which is an adaptive
format, which changes according to the values involved, as well
as according to various formatting flags. For similar
historical reasons: the default format will suppress trailing
zeros after the point, and if there are no digits after the
point, it will suppress the point as well. If you specify
showpoint, the results are the equivalent of %#g, which not
only causes the point to be displayed, regardless, but also
causes trailing zeros to be displayed.
In practice, this default format is almost never what you want
for real program output; its only real use is for debugging, and
various "informational" output. If you want fixed point, with
a fixed number of decimals after the point, you have to specify
it:
std::cout.setf( std::ios_base::fixed, std::ios_base::floatfield );
Normally, this will be done in some sort of hand written
manipulator, so that the format for a specific semantic value is
specified once (in the manipulator), and then you use the
manipulator to specify the signification of the value to be
output, something like:
std::cout << weight << someWeight;
For quick, throw away code, it's often convenient to have some
sort of generic specifiers as well; I've got something like:
class FFmt
{
int myWidth;
int myPrecision;
public:
FFmt( int width, int precision = 6 )
: myWidth( width )
, myPrecision( precision )
{
}
friend std::ostream& operator<<( std::ostream& dest, FFmt const& fmt )
{
dest.setf( std::ios_base::fixed, std::ios_base::floatfield );
dest.precision( myPrecision );
dest.setw( myWidth );
return dest;
}
};
(Actually, my version is more complex, because it derives from
a base class which saves the current formatting options in the
<< operator, and restores them in the destructor; since such
classes are used almost exclusively as temporaries, this means
at the end of the full expression.)
This supports writing things like:
std::cout << FFmt( 9, 6 ) << x;
Not something you'd want in production code (since you don't want to
specify the format at the point you're outputting the data), but
quite useful for quick, one time programs.
I have a code in which user has to pass > 0 number otherwise this code will throw. Using type of this arg as std::size_t doesn't work for the reason that negative numbers give large positive numbers. Is it good practice if I use signed type or are there other ways to enforce it?
void f(std::size_t number)
{
//if -1 is passed I'm (for obvious reason) get large positive number
}
I don't think there's a definitive correct answer to this question. You can take an look to Scott Meyers's opinion on the subject :
One problem is that unsigned types
tend to decrease your ability to
detect common programming errors.
Another is that they often increase
the likelihood that clients of your
classes will use the classes
incorrectly.
In the end, the question to ask is really : do you need the extra possible values provided by the unsigned type ?
A lot depends on what type of argument you imagine your clients trying to pass. If they're passing int, and that's clearly big enough to hold the range of values you're going to use, then there's no practical advantage to using std::size_t - it won't enforce anything, and the way the issue manifests as an apparently huge number is simply more confusing.
BUT - it is good to use size_t anyway as it helps document the expectations of the API.
You clearly can't do a compile-time check for "> 0" against a run-time generated value, but can at least disambiguate negative inputs from intentional huge numbers ala
template <typename T>
void f(T t)
{
if (!(t > 0))
throw std::runtime_error("be positive!");
// do stuff with t, knowing it's not -1 shoehorned into size_t...
...
}
But, if you are really concerned about this, you could provide overloads:
// call me please e.g. f(size_t(10));
void f(size_t);
// unimplemented (and private if possible)...
// "want to make sure you realise this is unsigned: call f(size_t) explicitly
void f(int32_t);
void f(int64_t);
...then there's a compile-time error leading to the comments re caller explicitly providing a size_t argument (casting if necessary). Forcing the client to provide an arg of size_t type is a pretty good way to make sure they're conscious of the issue.
Rin's got a good idea too - would work really well where it works at all (depends on there being an signed int type larger than size_t). Go check it out....
EDIT - demonstration of template idea above...
#include <iostream>
template <typename T>
void f(T t)
{
if (!(t > 0))
std::cout << "bad call f(" << (int)t << ")\n";
else
std::cout << "good f(" << (int)t << ")\n";
}
int main()
{
f((char)-1);
f((unsigned char)255);
}
I had the same problems you're having: Malfunctioning type-casting of string to unsigned int
Since, in my case, I'm getting the input from the user, my approach was to read the data as a string and check its contents.
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 (input[0] == '-' && std::numeric_limits<T>::min() == 0) {
throw InvalidInput<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;
}
}
}
If your allowed value range for number allows it use the signed std::ptrdiff_t (like Alexey said).
Or use a library like SafeInt and have f declared something like this: void f( SafeInt< std::size_t > i ); which throws if you'll call it with something like f( -1 );.
Fisrt solution
void f(std::ptrdiff_t number) {
if (number < 0) throw;
}
Second solution
void f(std::size_t number) {
if (number > std::numeric_limits<std::size_t>::max()/2) throw;
}
Maybe you should wrap read-function to another function which purpose will be get int and validate it.
EDIT: Ok int was just first idea, so read and parse string
This is one of the situations where you cannot really do much. The compiler usually gives out a warning when converting signed to unsigned data-types, so you will have to trust the caller to heed that warning.
You could test this using bitwise operation, such as the following:
void f(std::size_t number)
{
if(number & (0x1L << (sizeof(std::size_t) * 8 - 1)) != 0)
{
// high bit is set. either someone passed in a negative value,
// or a very large size that we'll assume is invalid.
// error case goes here
}
else
{
// valid value
}
}
This code assumes 8-bit bytes. =)
Yes, large values will fail, but you could document that they are not allowed, if you really need to protect against this.
Who is using this API? Rather than using a solution like this, I would recommend that they fix their code. =) I would think that the "normal" best practice would be for callers to use size_t, and have their compilers complain loudly if they try to put signed values into them.
I had to think about this question a little, and this is what I would do.
If your function has the responsability to throw an exception if you pass a negative number, then your function's signature should accept a signed integer number. That's because if you accept an unsigned number, you won't ever be able to tell unambiguosly if a number is negative and you won't be able to throw an exception. IOW, you want complain to your assignment of throwing exception.
You should establish what is an acceptable input range and use a signed integer large enough to fully contain that range.