Weird output!

Consider the code below:

1
2
3
int nbr = 7;
string str = "Hello world";
cout << str << ' : ' << nbr << endl;


I putted the string literal " : " inside the single quotes instead the double quotes, and I got this output:

Hello world21120327

Can you explain why I got this output? why the " : " transformed to 2112032 ?
' : ' is a multicharacter literal. It has type int.
Its value is implementation-defined, but mainstream implementations just concatenate bytes so that '\x11\x22\x33\x44' has the value 0x11223344. In general these are rarely useful.
https://en.cppreference.com/w/cpp/language/character_literal
Last edited on
mbozzi wrote:
In general these are rarely useful.

GCC doesn't enable many warnings by default but this one is, probably because it's seldom useful and it's easy to make a mistake and use single quotes instead of double quotes.

GCC wrote:
warning: multi-character character constant
Last edited on
In your example, you use simple quotes - and the code works as expected because it converts chars into decimal. Use double quotes for string literals - exactly like you did for the string Hello World. Just for info, I have no warning under Visual Studio 17.1.6 ++

1
2
3
4
5
6
7
8
9
10
#include <iostream>

int main()
{
    int nbr = 7;
    std::string str = "Hello world";
    std::cout << str << " : " << nbr << std::endl;

    return 0;
}



Last edited on
Thanks @Geckoo, I am not trying to fix the code here, I am trying to find out where that number comes from, the explanation already given by @mbozzi, so right now I am doing some reading trying to figure out:
what is those '\x11\x22\x33\x44' and what is the mainstream implementations

thank you @mbozzi btw
A simple change to your program will display that multi-character literal in hex.
1
2
3
4
5
6
7
8
#include <iostream>
int main()
{
	std::cout << std::hex << ' : ' << std::endl;
	return 0;
}
...
203a20

x20 is of course hex for a space. x3a is the ASCII value of a colon.
I ran this on MSVC 17.6.3 17.3.3, but I suspect other mainstream implementations would be the same.

Edit: corrected the VS version
Last edited on
That's genius @AbstractionAnon, 203a20 is actually the hex of the decimal number 2112032

I tried this:
2*16^5+0*16^4+3*16^3+10*16^2+2*16^1+0*16^0. And I got the 2112032.

Now for the sake of playing:
' ' = 32
':' = 58
' ' = 32

Can you try getting 2112032 ), or should I say, try to decrypt the 2112032, to get those 32 and 58. The war depend on It mates.
Last edited on
I can try to decrypt the 2112032

Could be

1
2
3
4
5
6
7
8
9
10
11
12
#include <cstdint>
#include <iostream>

int main()
{
  std::int32_t const n = ' : '; 
  std::cout << n << '\n';
  std::cout << ((n & 0xff << 24) >> 24) << ' '
            << ((n & 0xff << 16) >> 16) << ' '
            << ((n & 0xff <<  8) >>  8) << ' '
            << ((n & 0xff <<  0) >>  0) << '\n';  
}
2112032
0 32 58 32
Last edited on
Amazing you did it @mbozzi), my respect )

I am letting the topic unresolved for the moment, maybe someone can give another shot with another method)
C++20 using std::format:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <format>   // https://en.cppreference.com/w/cpp/utility/format/format

int main()
{
   unsigned n { ' : ' };

   std::cout << n << "\n\n";

   std::cout << std::format("{}\n\n", n);

   std::cout << std::format("{0:d}\n{0:b}\n{0:o}\n{0:#x}\n", n);
}
2112032

2112032

2112032
1000000011101000100000
10035040
0x203a20

If'n <format> isn't yet implemented, GCC/MinGW doesn't have it at this time, there is the {fmt} library:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <fmt/core.h>   // https://fmt.dev/latest/index.html

int main()
{
   unsigned n { ' : ' };

   std::cout << n << "\n\n";

   std::cout << fmt::format("{}\n\n", n);

   std::cout << fmt::format("{0:d}\n{0:b}\n{0:o}\n{0:#x}\n", n);
}

It is possible to get better output formatting for binary and hex representation, octal isn't as easily recognizable as being octal output:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <format>

int main()
{
   unsigned n { ' : ' };

   std::cout << n << "\n\n";

   std::cout << std::format("{}\n\n", n);

   std::cout << std::format("{0:0d}\n{0:#0b}\n{0:#0o}\n{0:#0x}\n", n);
}
2112032

2112032

2112032
0b1000000011101000100000
010035040
0x203a20

A (somewhat) in-depth explanation of what the format fields do:
https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification

The format specification is based on the format specification in Python:
https://docs.python.org/3/library/string.html#formatspec
ninja01 wrote:
what is the mainstream implementations

When I read "mainstream implementations" I mainly think of GCC, Clang and Microsoft's implementation (i.e. MSVC, VS, Visual C++, or whatever you call it ;)).
Last edited on
Thank you everyone)
Topic archived. No new replies allowed.