Is cout.put() recommended over cout<< for printing characters - c++

Background
IIRC, from Release 2.0 C++ stores single-character constants as type char and NOT int. But before Release 2.0 a statement like
cout<<'A'
was problematic as it displays the ASCII value of 'A' ie 65 whereas:
char ch='A';
cout<<ch;
would display the right value ie 'A'.
Since the problem has been rectified in Release 2.0. I believe cout.put() lost the advantage it had over cout<<.
Question
Is there any other reason for recommending cout.put() over cout<< for printing characters?

There are a few differences between cout<< and cout.put, or should we say the overloaded << operator and the put method from std::basic_ostream because this is not really limited to the global instance: cout.
The << operator writes formatted output, the put method does not.
The << operator sets the failbit if the output fails, the put method does not.
Personally I would go with the << operator in almost all cases, unless I had specific needs to bypass the formatted output or not setting the failbit on error.
Using them can result in the following differences of output:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << "Character: '" << setw(10) << 'A' << setw(0) << "'" << endl;
cout << "Character: '" << setw(10);
cout.put('A');
cout << setw(0) << "'" << endl;
return 0;
}
Outputs:
Character: ' A'
Character: 'A'
See the above in action: http://ideone.com/9N0VYn
Since the put method is unformatted it does not respect the manipulator set, there might be situations where that is indeed what you intend. But since it sounds like you only want to print out the character, I would prefer the << operator, which respects the formatting.
And then there is the case of the failbit which is not being set, and that might even be more crucial.

Related

Why is stringstream mixing up it's content in combination with char array and cout?

in this minimal example there is a weird messing up between the input to a stringstream and the content of a previously used cout:
online gdb:
https://onlinegdb.com/itO69QGAE
code:
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
const char sepa[] = {':', ' '};
const char crlf[] = {'\r', '\n'};
int main()
{
cout<<"Hello World" << endl;
stringstream s;
string test1 = "test_01";
string test2 = "test_02";
s << test1;
cout << s.str() << endl;
// works as expected
// excpecting: "test_01"
// output: "test_01"
s << sepa;
cout << s.str() << endl;
// messing up with previous cout output
// expecting: "test_01: "
// output: "test_01: \nHello World"
s << test2;
cout << s.str() << endl;
// s seems to be polluted
// expecting: "test_01: test_02"
// output: "test_01: \nHello Worldtest_02"
s << crlf;
cout << s.str() << endl;
// once again messing up with the cout content
// expecting: "test_01: test_02\r\n"
// output: "test_01: Hello Worldtest_02\r\nHello World"
return 0;
}
So I am wondering why is this happing?
As it only happens when a char array is pushed into the stringstream it's likely about this... but according to the reference the stringstream's "<<"-operator can/should handle char* (what actually the name of this array stand's for).
Beside that there seems to be a (?hidden, or at least not obvious?) relation between stringstream and cout. So why does the content pollute into the stringstream?
Is there any wrong/foolish usage in this example or where is the dog buried (-> german idiom :P )?
Best regards and thanks
Damian
P.S. My question is not about "fixing" this issue like using a string instead of the char array (this will work)... it's about comprehend the internal mechanics and why this is actually happing, because for me this is just an unexpected behaviour.
The std::stringstream::str() function returns a string containing all characters previously written into the stream, in all previous calls to operator<< (or other output functions). However it seems that you expect that only the last output operation will be returned - this is not the case.
This is analogous to how e.g. std::cout works: each invocation of std::cout << appends the string to standard output; it does not clear the console's screen.
To achieve what you want, you either need to use a separate std::stringstream instance every time:
std::stringstream s1;
s1 << test1;
std::cout << s1.str() << std::endl;
std::stringstream s2;
s2 << sepa;
std::cout << s2.str() << std::endl;
Or better, clear the contents of the std::stringstream using the single argument overload of the str() function:
std::stringstream s;
s << test1;
std::cout << s.str() << std::endl;
// reset the contents of s to an empty string
s.str("");
s << sepa;
std::cout << s.str() << std::endl;
The s.str("") call effectively discards all characters previously written into the stream.
Note, that even though std::stringstream contains a clear() function that would seem a better candidate, it's not analogous to e.g. std::string::clear() or std::vector::clear() and won't yield the effect desired in your case.
Here I am again,
Thanks to "Some programmer dude"'s comment I think I figured it out:
As there is no (null-)termination-symbol related to both char arrays it seems that the stringstream-<<-operator inserts until it stumbles over an null-terminator '\0'.
Either expending both arrays with a \0-symbol (e.g. const char sepa[] = {':', ' ', '\0'}) or terminating the length with e.g. s << string(sepa,2) will do the expected output.
In this specific case above the data seems to lay aligned in memory, so that the next null-terminator will be found inside the cout << "Hello World"-statement. As this alignment is not guaranteed, this will actually result in undefined behaviour, when the termination is missing.
So also two additional "terminating"-arrays like e.g const char sepa[] = {':', ' '}; char[] end_of_sepa = {'\0'}; declared right after the mentioned arrays will result in expected output, eventhough when the rest will be left unchanged... but this is probably not guaranteed and depends on the internal representation in memory.
P.S. As previously written this issue is not about fixing but comprehension. So please feel free to confirm or correct my assumption.
EDIT: Corrected the bold code section.

What is the sequence a compiler processes information (strings, manipulators etc.) when encountered with an extraction or insertion operator?

I am unsure as to why this line works. How does a compiler work to make this line of code perfectly legal. Does the cout process information from left to right, neglecting the information till the next extraction operator?
How does a compiler identify how to sequence the multiple existing strings?
std:: cout << "Hello world" << " this is a new line" << endl;
This works based on two mechanics:
When cout (or cin or another stream from the <iostream> library) has the << or >> operator called, it returns itself after doing the input or output. Therefore, cout << "Hello world" works just like cout for the rest of the line.
The operator<< call is left-to-right associative; that is, your line is equivalent to ((std::cout << "Hello world") << " this is a new line") << endl;. Combined with point 1, this means that it works like running cout << "Hello world";, followed by cout << " this is a new line"; and cout << endl;.
As a side note, in most cases you don't actually need endl. You should just include a newline in the string itself, as " this is a new line\n". The only time you need to use endl is if you actually need the line to appear on the screen right away, which you usually don't. Because endl forces the line to appear immediately (it flushes the buffer), it takes a lot longer than just using a newline character.
<< is really just operator<<. That overload for std::ostream returns itself to allow chaining of multiple operator<< calls so really it's just:
foo.print("Hello world").print(" this is a new line").print("\n");

whether io manipulators has to be set for every time in ostringstream? [duplicate]

I recently had a problem creating a stringstream due to the fact that I incorrectly assumed std::setw() would affect the stringstream for every insertion, until I changed it explicitly. However, it is always unset after the insertion.
// With timestruct with value of 'Oct 7 9:04 AM'
std::stringstream ss;
ss.fill('0'); ss.setf(ios::right, ios::adjustfield);
ss << setw(2) << timestruct.tm_mday;
ss << timestruct.tm_hour;
ss << timestruct.tm_min;
std::string filingTime = ss.str(); // BAD: '0794'
So, I have a number of questions:
Why is setw() this way?
Are any other manipulators this way?
Is there a difference in behavior between std::ios_base::width() and std::setw()?
Finally is there an online reference that clearly documents this behavior? My vendor documentation (MS Visual Studio 2005) doesn't seem to clearly show this.
Important notes from the comments below:
By Martin:
#Chareles: Then by this requirement all manipulators are sticky. Except setw which seems to be reset after use.
By Charles:
Exactly! and the only reason that setw appears to behave differently is because there are requirements on formatted output operations to explicitly .width(0) the output stream.
The following is the discussion that lead to the above conclusion:
Looking at the code the following manipulators return an object rather than a stream:
setiosflags
resetiosflags
setbase
setfill
setprecision
setw
This is a common technique to apply an operation to only the next object that is applied to the stream. Unfortunately this does not preclude them from being sticky. Tests indicate that all of them except setw are sticky.
setiosflags: Sticky
resetiosflags:Sticky
setbase: Sticky
setfill: Sticky
setprecision: Sticky
All the other manipulators return a stream object. Thus any state information they change must be recorded in the stream object and is thus permanent (until another manipulator changes the state). Thus the following manipulators must be Sticky manipulators.
[no]boolalpha
[no]showbase
[no]showpoint
[no]showpos
[no]skipws
[no]unitbuf
[no]uppercase
dec/ hex/ oct
fixed/ scientific
internal/ left/ right
These manipulators actually perform an operation on the stream itself rather than the stream object (Though technically the stream is part of the stream objects state). But I do not believe they affect any other part of the stream objects state.
ws/ endl/ ends/ flush
The conclusion is that setw seems to be the only manipulator on my version that is not sticky.
For Charles a simple trick to affect only the next item in the chain:
Here is an Example how an object can be used to temporaily change the state then put it back by the use of an object:
#include <iostream>
#include <iomanip>
// Private object constructed by the format object PutSquareBracket
struct SquareBracktAroundNextItem
{
SquareBracktAroundNextItem(std::ostream& str)
:m_str(str)
{}
std::ostream& m_str;
};
// New Format Object
struct PutSquareBracket
{};
// Format object passed to stream.
// All it does is return an object that can maintain state away from the
// stream object (so that it is not STICKY)
SquareBracktAroundNextItem operator<<(std::ostream& str,PutSquareBracket const& data)
{
return SquareBracktAroundNextItem(str);
}
// The Non Sticky formatting.
// Here we temporariy set formating to fixed with a precision of 10.
// After the next value is printed we return the stream to the original state
// Then return the stream for normal processing.
template<typename T>
std::ostream& operator<<(SquareBracktAroundNextItem const& bracket,T const& data)
{
std::ios_base::fmtflags flags = bracket.m_str.flags();
std::streamsize currentPrecision = bracket.m_str.precision();
bracket.m_str << '[' << std::fixed << std::setprecision(10) << data << std::setprecision(currentPrecision) << ']';
bracket.m_str.flags(flags);
return bracket.m_str;
}
int main()
{
std::cout << 5.34 << "\n" // Before
<< PutSquareBracket() << 5.34 << "\n" // Temp change settings.
<< 5.34 << "\n"; // After
}
> ./a.out
5.34
[5.3400000000]
5.34
The reason that width does not appear to be 'sticky' is that certain operations are guaranteed to call .width(0) on an output stream. Those are:
21.3.7.9 [lib.string.io]:
template<class charT, class traits, class Allocator>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os,
const basic_string<charT,traits,Allocator>& str);
22.2.2.2.2 [lib.facet.num.put.virtuals]: All do_put overloads for the num_put template. These are used by overloads of operator<< taking a basic_ostream and a built in numeric type.
22.2.6.2.2 [lib.locale.money.put.virtuals]: All do_put overloads for the money_put template.
27.6.2.5.4 [lib.ostream.inserters.character]: Overloads of operator<< taking a basic_ostream and one of the char type of the basic_ostream instantiation or char, signed char or unsigned char or pointers to arrays of these char types.
To be honest I'm not sure of the rationale for this, but no other states of an ostream should be reset by formatted output functions. Of course, things like badbit and failbit may be set if there is a failure in the output operation, but that should be expected.
The only reason that I can think of for resetting the width is that it might be surprising if, when trying to output some delimited fields, your delimiters were padded.
E.g.
std::cout << std::setw(6) << 4.5 << '|' << 3.6 << '\n';
" 4.5 | 3.6 \n"
To 'correct' this would take:
std::cout << std::setw(6) << 4.5 << std::setw(0) << '|' << std::setw(6) << 3.6 << std::setw(0) << '\n';
whereas with a resetting width, the desired output can be generated with the shorter:
std::cout << std::setw(6) << 4.5 << '|' << std::setw(6) << 3.6 << '\n';
setw() only affects the next insertion. That's just the way setw() behaves. The behavior of setw() is the same as ios_base::width(). I got my setw() information from cplusplus.com.
You can find a full list of manipulators here. From that link, all the stream flags should stay set until changed by another manipulator. One note about the left, right and internal manipulators: They are like the other flags and do persist until changed. However, they only have an effect when the width of the stream is set, and the width must be set every line. So, for example
cout.width(6);
cout << right << "a" << endl;
cout.width(6);
cout << "b" << endl;
cout.width(6);
cout << "c" << endl;
would give you
> a
> b
> c
but
cout.width(6);
cout << right << "a" << endl;
cout << "b" << endl;
cout << "c" << endl;
would give you
> a
>b
>c
The Input and Output manipulators are not sticky and only occur once where they are used. The parameterized manipulators are each different, here's a brief description of each:
setiosflags lets you manually set flags, a list of which can be found here, so it is sticky.
resetiosflags behaves similar to setiosflags except it unsets the specified flags.
setbase sets the base of integers inserted into the stream (so 17 in base 16 would be "11", and in base 2 would be "10001").
setfill sets the fill character to insert in the stream when setw is used.
setprecision sets the decimal precision to be used when inserting floating point values.
setw makes only the next insertion the specified width by filling with the character specified in setfill

cout and sizeof are not returning what I expect in C++

Here is sth I find but I can't understand one address ,when I use "cout<
#include<iostream>
using namespace std;
int main()
{
char a[2]={'a','b'};
char b[3]="ab";
cout<<&a<<endl;
cout<<&b<<endl;
cout<<sizeof(a)<<endl<<cout<<sizeof(b);//the result of this I am puzzled
return 0;
}
The result is :
0x28ff2e
0x28ff10
2
0x4453c43
0x28ff2e is an address of a
0x28ff10 is an address of b
2 is the size of a
0x4453c43 is an address of the result of converting cout to void* followed by sizeof(b) (See Does std::cout have a return value?)
Maybe you did want this instead:
cout << sizeof(a) << endl;
cout << sizeof(b) << endl;
Or this:
cout << sizeof(a) << endl << sizeof(b) << endl;
When you do this line:
cout<<sizeof(a)<<endl<<cout<<sizeof(b)
You shouldn't use cout second time. When you do, you printf address of it:
0x4453c4
or rather Does std::cout have a return value?
and then you print size of b, is the 3 on the end of this 0x4453c43
Rather you should just use this:
cout<< sizeof(a) << endl << sizeof(b) << endl;
You're printing the address of cout ;)
cout<<sizeof(a)<<endl<<cout<<sizeof(b)
The problem is that you're streaming the cout object to itself, so it prints whatever the cout can be converted to that operator<< if overloaded for - which happens to be void* (before C++11, which you evidently aren't using).
Either break cout<<sizeof(a)<<endl<<cout<<sizeof(b); into two lines with a semicolon after endl, or remove the second cout. You should put in a final endl or '\n' too... on some systems you won't be able to read the output otherwise (as the shell prompt will return to the left-of-screen then overwrite it).
You probably don't want this bit:
cout<<sizeof(a)<<endl<<cout<<sizeof(b);
^^^^^^
Older implementations of streams had an operator void*(), to allow constructs like if (cout) without allowing implicit conversions to bool and other numeric types; you are seeing the result of that, concatenated with the final value. A C++11 implementation should have an explicit operator bool() insead, and so should cause a compile error here.
Removing that gives something like:
0x28ff2e
0x28ff10
2
3
as you would expect.
"the result of this I am puzzled"
cout< < sizeof(a)< <endl << cout <<sizeof(b);
^^^ The "puzzling" address comes from this
Remove it and see the result
cout output to standard output is implementation defined
You have a stray cout there. Note that you're effectively printing cout into cout here:
cout << ... << cout << sizeof(b);
cout needs some form of conversion to boolean. Before C++11, this was provided by a conversion to void*; this happens in your case, as the only way cout can be converted to something streamable. Note that there's an extra 3 after 6 hexa digits of the pointer - that's the 3 produced by sizeof(b)

Right Justifying output stream in C++

I'm working in C++. I'm given a 10 digit string (char array) that may or may not have 3 dashes in it (making it up to 13 characters). Is there a built in way with the stream to right justify it?
How would I go about printing to the stream right justified? Is there a built in function/way to do this, or do I need to pad 3 spaces into the beginning of the character array?
I'm dealing with ostream to be specific, not sure if that matters.
You need to use std::setw in conjunction with std::right.
#include <iostream>
#include <iomanip>
int main(void)
{
std::cout << std::right << std::setw(13) << "foobar" << std::endl;
return 0;
}
Yes. You can use setw() to set the width. The default justification is right-justified, and the default padding is space, so this will add spaces to the left.
stream << setw(13) << yourString
See: setw(). You'll need to include <iomanip>.
See "setw" and "right" in your favorite C++ (iostream) reference for further details:
cout << setw(13) << right << your_string;
Not a unique answer, but an additional "gotcha" that I discovered and is too long for a comment...
All the formatting stuff is only applied once to yourString. Anything additional, like << yourString2 doesn't abide by the same formatting rules. For instance if I want to right-justify two strings and pad 24 asterisks (easier to see) to the left, this doesn't work:
std::ostringstream oss;
std::string h = "hello ";
std::string t = "there";
oss << std::right << std::setw(24) << h << t;
std::cout << oss.str() << std::endl;
// this outputs
******************hello there
That will apply the correct padding to "hello " only (that's 18 asterisks, making the entire width including the trailing space 24 long), and then "there" gets tacked on at the end, making the end result longer than I wanted. Instead, I wanted
*************hello there
Not sure if there's another way (you could simply redo the formatting I'm sure), but I found it easiest to simply combine the two strings into one:
std::ostringstream oss;
std::string h = "hello ";
std::string t = "there";
// + concatenates t onto h, creating one string
oss << std::right << std::setw(24) << h + t;
std::cout << oss.str() << std::endl;
// this outputs
*************hello there
The whole output is 24 long like I wanted.
Demonstration