Standard Stream Printing Unrelated Characters - c++

I was coding something and my code didn't work correctly in some situations, so I decided to write some output to file for debugging. The program just concatenates some characters from a string (and it didn't get out of bounds) and printed them to the file. It has no thing as error reporting or something, and the input string is just a bunch of random characters. But, i get some junk in the output, such as:
f::xsgetn error reading the file
sgetn error reading the file
ilebuf::xsgetn error reading the file
(I removed program's output and this is just the extra stuff.)
As far as I know, if there are any errors, an exception must be thrown. What happens and how can I fix it?
The same thing happens when I print the output using standard output. All used libraries are standard libraries (eg. iostream, fstream, etc.)
PS: For some reasons, I can't publish all the code. Here is the part that creates the output and passes it to stream: (tri is and string, and is defined previously. Center is an integer and is inside the bounds of the string. fout is a previously defined file stream.)
string op = "" + tri[center];
fout << center << "<>" << op << endl;

Since tri is a string, tri[center] is a char.
The type of "" is const char[], which can't be added to a char.
Instead it is implicitly converted to const char*, which can be added to a char.
Unfortunately for you, the result of that is that the integer value of tri[center]is added to that pointer as an offset, not as a string concatenation, and the particular area of memory that the result refers to doesn't contain what you're looking for but instead contains other static strings like e.g. "error reading the file".
To fix it, use
string op = string("") + tri[center];
instead.

I encountered the same problem in another program, where I had written:
str += blablabla + "#";
and I saw some unrelated characters being printed. I fixed it this way:
str = str + blablabla + "#";
and it worked!
There is some problem with the += operator for string.

Related

Printing char arrays c++

I was playing around with c strings in c++ and found some behavior I don't understand when I don't terminate a char array.
char strA[2] = {'a','\0'};
char strB[1] = {'b'};
cout << strA << strB;
I would expect this to print ab, but instead it prints aba. If I instead declare strB before strA, it works as expected. Could someone explain what's going on here?
This is undefined behaviour and you simply are lucky that replacing the declaration of these 2 arrays works for you. Let's see what is happening in your code:
char strA[2] = {'a','\0'};
Creates an array that can be treated like a string - it is null terminated.
char strB[1] = {'b'};
Creates an array that cannot be treated like a string, because it lacks the null terminating character '\0'.
std::cout << strA << strB;
The first part, being << strA, works fine. It prints a since strA is treated as a const char*, which provided as an argument for std::ostream& operator << will be used to print every character untill the null terminating character is encountered.
What happens then? Then, the << strB is being executed (actually what happens here is a little different and more complicated than simply dividing this line into two, separate std::cout << calls, but it does not matter here). It is also treated as a const char*, which is expected to ended with mentioned '\0', however it is not...
What does that lead to? You are lucky enough that there randomly is only 1 character before (again - random) '\0' in memory, which stops the (possibly near-infinite) printing process.
Why, if I instead declare strB before strA, it works as expected?
That is because you were lucky enough that the compiler decided to declare your strA just after the strB, thus, when printing the strB, it prints everything that it consists + prints strA, which ends with null terminating character. This is not guaranteed. Avoid using char[] to represent and print strings. Use std::string instead, which takes care of the null terminating character for you.
When printing char arrays, the C (and C++) convention is to print all bytes until a '\0'.
Because of how the local variables are organized, strB's memory is behind strA's, so when printing strB the printing just 'overflows' and keeps printing strA until the terminating '\0'.
I guess when the deceleration is reversed, the printing of strB is terminated by a 0 that is just there because nothing else was set there, but you shouldn't rely on that - this is called a garbage value.
Don't use unterminated C-strings, at all. Also avoid C-strings in general, you can use C++ std::string which are much more secure and fun.
When I run this code on my computer, I have a bunch (exactly seven) of weird chars printed between the ab to the a, which are probably whatever was between strA's and strB's memory spaces.
When I reverse the declarations, I get ab$%^& where $%^& are a bunch of weird chars - the ones between the end of strB's memory to the next random \0.

c++ string_literals s postfix cant print string concatenated this way

I'm trying to learn about string literals and the likes and I've been playing around with it. Currently facing the problem of being unable to wcout a string that was the concatenation of two string literals appended with the "string"s method.
std::string concat = "Hello, "s + "World!";
It doesn't have any compiler errors if I cast to a string or make a call to a string constructor to concatenate them.
I'm also having trouble getting wcout to actually output unicode characters. I use cout elsewhere in the code.
constexpr wchar_t* surname = L"shirts \u0444 \u1300";
outputs shirts but no unicode characters when I wcout << surname; If I just cout surname I get hex.
Edit: thanks to comments I have understood the problem of wcout. I didn't realize it would only work with wstring and I was avoiding ordinary cout due to having read something about not mixing the two that I have yet to fully understand.
I still can't get the symbols to print out in wchar_t* which just outputs ordinary ascii characters.
Thanks for the swift replies thus far!
wcout works for normal chars marked with u8 but nothing else it seems. Several wcout statements just aren't outputting anything after the shirt fail, I moved them before it and they were printed out but they were hex rather than characters as expected. So far only normal char* have worked. This is such a headache...
As for no Unicode console output, you may have to set the locale, that is:
std::setlocale(LC_ALL, "");
constexpr wchar_t* surname = L"shirts \u0444 \u1300";
wcout << surname;

cout string and c_str gives different values in c++

In my code, I have a string variable named ChannelPacket.
when I print Channelpacket in gdb, it gives following string :
"\020\000B\001\237\246&\b\000\016\000\002\064\001\000\000\005\000\021\002\000\000\006\000\f\001\001\000\000sZK"
But if i print Channelpacket.c_str(), it gives just "\020 output.
Please help me.
c_str() returns a pointer to char that's understood to be terminated by a NUL character ('\0').
Since your string contains an embedded '\0', it's seen as the end of the string when viewed as a pointer to char.
When viewed as an actual std::string, the string's length is known, so the whole thing is written out, regardless of the embedded NUL characters.
The second byte is a zero, which means the end of the string. If you want to output the raw bytes, rather than treating them as a null-terminated string, you can't use cout << Channelpacket.c_str() - use cout << Channelpacket instead.

cout input stream with and without (void*)

I have a input stream IPCimstream, which returns a pointer to the character buffer of its stream with dataBuf() function.
Say I have
IPCimstream ims;
What is the difference between printing
1.
cout << ims.dataBuf() << endl;
and
2.
cout << (void*)ims.dataBuf() << endl;
If possible pls explain with an example. Say ims.dataBuf() has "Hello world\n", etc. or other examples which you feel explain the difference well. Sorry I am new to input stream and I couldnt come up with more interesting examples if there might be any.
Also, what would be the difference if IPCimstream is a character stream vs. binary stream. Thanks.
Well, the difference is that char* overload of cout::operator<< treats the pointer as a zero-terminated C string (well, C strings are just char pointers anyway), so it outputs the string itself. If your buffer is not a zero-terminated string, the cout's guess is wrong, so it will output some random garbage till the first \0.
The void* version of the same operator doesn't know what is the object behind the pointer, so everything it can do is just to output the pointer value.
You see, this behaviour is not connected with the IPCimstream class, it's just how cout works. (Look at teh example at http://ideone.com/1ErtV).
Edit:
In the case if dataBuf containing "Hello world\n" the char* version interprets the pointer as a zero-terminated string. So it will output the characters "Hello world", output the newline character, and than all the characters that happen to be in the memory after \n till the next \0. If there is no such character in the memory, the program may just crash. (For language purists: you'll get undefined behaviour.)
The void* version doesn't know how to treat the value pointed to by the pointer -- so it outputs the pointer value (i.e., the address) itself.
Edit 2:
The difference between the character stream and binary stream may be only in the data they hold. In any case, if dataBuf() returns a char*, the cout will output all the characters found in the buffer (and potentially beyond it) until the first \0 (or just nothing if \0 is at the beginning), and with the cast you'll get just the buffer's address output as string.

Does sending a character pointer - initialized to '\0' - to the standard output fault it? (C++)

This is trivial, probably silly, but I need to understand what state cout is left in after you try to print the contents of a character pointer initialized to '\0' (or 0). Take a look at the following snippet:
const char* str;
str = 0; // or str = '\0';
cout << str << endl;
cout << "Welcome" << endl;
On the code snippet above, line 4 wont print "Welcome" to the console after the attempt to print str on line 3. Is there some behavior I should be aware of? If I substitute line 1-3 with cout << '\0' << endl; the message "Welcome" on the following line will be successfully printed to the console.
NOTE: Line 4 just silently fails to print. No warning or error message or anything (at least not using MinGW(g++) compiler). It spewed an exception when I compiled the same code using MS cl compiler.
EDIT: To dispel the notion that the code fails only when you assign str to '\0', I modified the code to assign to 0 - which was previously commented
If you insert a const char* value to a standard stream (basic_ostream<>), it is required that it not be null. Since str is null you violate this requirement and the behavior is undefined.
The relevant paragraph in the standard is at §27.7.3.6.4/3.
The reason it works with '\0' directly is because '\0' is a char, so no requirements are broken. However, Potatoswatter has convinced me that printing this character out is effectively implementation-defined, so what you see might not quite be what you want (that is, perform your own checks!).
Don't use '\0' when the value in question isn't a "character"
(terminator for a null terminated string or other). That is, I think,
the source of your confusion. Something like:
char const* str = "\0";
std::cout << str << std::endl;
is fine, where str points to a string which contains a '\0' (in this
case, two '\0'). Something like:
char const* str = NULL;
std::cout << str << std::endl;
is undefined behavior; anything can happen.
For historical reasons (dating back to C), '\0' and 0 will convert
implicitly to any pointer type, resulting in a null pointer.
A char* that points to a null character is simply a zero-length string. No harm in printing that.
But a char* whose value is null is a different story. Trying to print that would mean dereferencing a null pointer, which is undefined behavior. A crash is likely.
Assigning '\0' to a pointer isn't really correct, by the way, even if it happens to work: you're assigning a character value to a pointer variable. Use 0 or NULL, or nullptr in C++11, when assigning to a pointer.
Just regarding the cout << '\0' part…
"Terminating the string" of a file or stream in text mode has an undefined effect on its contents. The C++ standard defers to the C standard on matters of text semantics (C++11 27.9.1.1/2), and C is pretty draconian (C99 §7.19.2/2):
Data read in from a text stream will necessarily compare equal to the data that were earlier written out to that stream only if: the data consist only of printing characters and the control characters horizontal tab and new-line; no new-line character is immediately preceded by space characters; and the last character is a new-line character.
Since '\0' is a control character and cout is a text stream, the resulting output may not read as you wrote it.
Take a look at this example:
http://ideone.com/8MHGH
The main problem you have is that str is pointer to a char not a char, so you should assign it to a string: str = "\0";
When you assign it to char, it remains 0 and then the fail bit of cout becomes true and you can no longer print to it. Here is another example where this is fixed:
http://ideone.com/c4LPh