3

I want to print 10°Celsius with printffunction

Normally I would do it like this:

printf("10\xF8Celsius");

where \xF8 is the ANSI code for degree sign. The problem is that the compiler take all hexadecimal characters after \x and tries to convert to a character, basically it takes \F8Ce and tries to convert it to a character.

I could write it like:

printf("10\xF8 Celsius"); //see additional space

but the question still remains.

How to tell compiler where my hexadecimal code ends? Is it possible?

Note: I used Visual Studio 2015 PRE on a Windows 8.1 to observe this problem (not that this problem is platform specific but just to mention it)

Alex
  • 5,510
  • 8
  • 35
  • 54

5 Answers5

5

Hex escape sequence has no character limit so - since parser is greedy - it grabs all hex digits it can get. C spec excerpt:

hexadecimal-escape-sequence:
    \x hexadecimal-digit
    hexadecimal-escape-sequence hexadecimal-digit

hexadecimal-digit: one of
    0 1 2 3 4 5 6 7 8 9
    a b c d e f
    A B C D E F

To remedy that - split your string into 2 consecutive and they will be later joined (in translation phase #6 ;-). So instead of:

printf("10\xF8Celsius");

use:

printf("10\xF8" "Celsius");
Artur
  • 7,038
  • 2
  • 25
  • 39
  • Cool solution. Did not know that you can put 2 string literals into `printf`function.... – Alex Jul 06 '15 at 11:40
  • 1
    You can put them anywhere you need. Adjacent strings will be concatenated into one (by preprocessor) even before compiler starts to work on them. The compiler will get one string and will not even know there might have been more strings in place where it receives just one. Printf will get one string (a pointer to a string to be precise) as an argument not two strings. – Artur Jul 06 '15 at 12:40
3

From C11 specs 6.4.4.4 Character constants

hexadecimal-escape-sequence:
        \x hexadecimal-digit
        hexadecimal-escape-sequence hexadecimal-digit

EXAMPLE 3 Even if eight bits are used for objects that have type char, the construction '\x123' specifies an integer character constant containing only one character, since a hexadecimal escape sequence is terminated only by a non-hexadecimal character. To specify an integer character constant containing the two characters whose values are '\x12' and '3', the construction '\0223' may be used, since an octal escape sequence is terminated after three octal digits. (The value of this two-character integer character constant is implementation-defined.)

So parser will try to parse as many characters of hexadecimal as available.

One workaround is to use string concatenation:

printf("10\xF8" "Celsius");

Live example

or

printf("10%cCelsius", '\xF8');

Or use equivalent octal escape sequence which is guaranteed to be not more than 3 characters long.


NOTE: Using '\xF8' to print is not portable and may not work on many platforms. You can use unicode string literal for a portable code.

Mohit Jain
  • 30,259
  • 8
  • 73
  • 100
2

From this C++ escape sequence reference:

Hexadecimal escape sequences have no length limit and terminate at the first character that is not a valid hexadecimal digit.

So without any workarounds there is simply no limit on the digits the compiler will read.

Note that the corresponding C reference says the same thing.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

The correct fix is to use the printf function as intended. Please look up printf-documentation.

printf("10%c Celsius", 0xF8)
Dlanod Kcud
  • 517
  • 5
  • 13
1

You can use an octal escape sequence instead of the hexadecimal escape sequecne. For example

printf("10\370Celsius");

From the C++ Standard (2.14.3 Character literals)

4 The escape \ooo consists of the backslash followed by one, two, or three octal digits that are taken to specify the value of the desired character....

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335