What is printing slash letters? eg: arduino.print('/a');?

Hi,
When I do
arduino.print(’/a’);

The result of this is a number. 12129 to be precise.
/b will be 12130.
And any consecutive letter adds +1 until I get /z (which equals 12154).
I can also print(’/A’) (capitol letter), which ranges from 12097-12122 for capitol Z.
ranges /0 to /9 prints out: 12080 to 12089
/10 to /19 prints out ranges 12592 to 12601.
/20 to /29 = 12136 - 12145

What is their name (what are they called), and what is the logic in all this?
Meaning, why is printing out these ‘slash letters’ or ‘slash numbers’, printing out 5 digit numbers?
And on what is this counting based?
I tried Hexadecimal numbers (00-FF) but it appears that the jump from 09 to 0A isn’t consecutive.
I don’t understand in what application this can be used, and how the counting works.
Sure, a-z is +1 number, easy.
Also from 0-9.
But there’s a large jump from 9 to 10. And /9 does not equal /09.

Edit:
So far it appears that the numbering system goes:
0-9, A-Z.
I suppose after Z comes characters.
Could this be a form of ASCII table numbering?

Thanks!

1 Like

OK, so after ‘Z’ comes ‘[’.
It appears to have an order of the ASCII table, but print out a different outcome, as capitol ‘Z’ in ascii has number 90 or 132, and the print result in Arduboy is 12122.

Also the upper value seems to be /999 resulting in 14649. printing out anything larger just ends up in 14649

http://www.asciitable.com/

I wonder what it’s used for, and if it has a different name, than just ‘ascii numbering’?

A ‘slash character’ s capped an escape sequence. The slash means that whatever is next will be replaced with it To create a special character or so something special. For instance, you can’t just push ENTER within your string to include a linebreak. Instead, you use the sequence \n to do that. There are some more useful ones like \t for tabs. To print a slash within a string, you need to use two slashes. \\ To include a quotation symbol ("), you use a slash before it. \" This is sometimes just called escaping characters amd a lot of languages use it.

There is a conversation on Stack Overflow you might find helpful: https://stackoverflow.com/questions/10220401/rules-for-c-string-literals-escape-character

Just note that a lot of old escape sequences come from a time when typewriters and old input devices could be used. So, we don’t see them used practically anymore.

although escapes are done with back slashes. I am unfamiliar with what forward slashes are doing, and googling doesn’t turn up much. Maybe pharap knows.

1 Like

True. Not only Arduino, it does it in normal C++ if you do cout << '/a' << endl;. I don’t know what’s going on, thought such char literal was illegal. I looked for a while on Google, in source codes and C++ specs, but wasn’t able to find it. @Pharap, do you know what’s going on here? :smiley:

1 Like

You need to put an ‘@’ in front to properly summon me.

(Either that or walk up a flight of stairs backwards holding a candle and a hand mirror. :P)

I’ve looked into it.

The forward slash is completely irrelevant.
What we’re looking at here is called a “multicharacter literal”.
It has a value of type int (which is why numbers are printed instead of characters, it’s calling print(int), not print(char)) and the exact value is actually implementation defined.

It’s item (6) on this page:
https://en.cppreference.com/w/cpp/language/character_literal

Note that 1-5 say c-char whilst the last is c-char-sequence.

  1. Multicharacter literal, e.g. ‘AB’, has type int and implementation-defined value.

I can look into figuring out how GCC is selecting the values, but I’m not sure it’s worthwhile because they’re “implementation defined” so it would only work on GCC.

I’d advise not using it, it seems pretty useless.
I don’t even know why it exists in the first place, but I do know it was inherited from C.

1 Like

In case anyone cares, it took me ~5-10 minutes to figure out what’s going on:

‘aa’ = 24929 = 0x6161 = 0b0110000101100001
‘ab’ = 24930 = 0x6162 = 0b0110000101100010
‘ba’ = 25185 = 0x6261 = 0b0110001001100001
‘bb’ = 25186 = 0x6262 = 0b0110001001100010

So basically it’s

'aa' == ('a' << 8) | ('a' << 0)
'ab' == ('a' << 8) | ('b' << 0)
'ba' == ('b' << 8) | ('a' << 0)
'bb' == ('b' << 8) | ('b' << 0)

And for longer cases:

'caa' == ('c' << 16) | ('a' << 8) | ('a' << 0)
'cab' == ('c' << 16) | ('a' << 8) | ('b' << 0)
'cba' == ('c' << 16) | ('b' << 8) | ('a' << 0)
'cbb' == ('c' << 16) | ('b' << 8) | ('b' << 0)

But of course, int is 16-bit, so the extra bits are lost.
I.e. only the last two characters matter.

Yes the back slashes I understand. Very few uses for them other than \n.
Although \a \b \e \f \g and \t give special characters on the screen.

It would be perhaps shorter to code using /a if you need the exact value of 12129, but it would be more tedious than writing the full number.
Would it save any memory doing things this way? Like, say, a game that’s maxed out on memory, saving bits by using this method?

Even though \n looks like two characters in the file editor, it is only 1 character when it is compiled, being the same value as what the enter key would produce.

When doing console programming on desktop, \r will erase the current line of text to allow you to continually overwrite a line.
Various console programs abuse that to create loading bars and counters that update themselves.

\a is supposed to make a console/terminal make a noise of some description, but it doesn’t always work.
(It still makes a noise on Windows 8, but it’s a tad quiet.)
The Arduboy will ignore that though.

\t is a horizontal tab.
I’m not sure how the Arduboy reacts to those, I think it either gives a regular space or ignores them.

\b is a backspace.
The Arduboy would no doubt ignore the original meaning because it can’t really ‘undraw’ a character after the character has been drawn.

\f is a form feed, which again doesn’t make sense on Arduboy so it just gets printed verbatim.

\e only works because the compiler is GCC.
I’m surprised that \g works. I have no idea what that would do because it’s non-standard.

Bear in mind that the Arduboy’s default font is based on the code page 437 character set:

If you go to the ‘Character Set’ section and cross reference it with an ASCII table then you should see why you get the characters that you do when using character escapes.

It would be shorter, but you shouldn’t do it because it’s cryptic.

Code should be explicit with its intent, it shouldn’t try to hide what it’s trying to do.
Laziness is the enemy of clean code.

No, none whatsover.

The type of the expression is int, so the literal will be interpreted as the same integer value regardless of whether it’s done as an integer literal or a multicharacter literal.

1 Like

From the Arduboy2 Library documentation for the write() function:


Two special characters are handled:

  • The newline character \n . This will move the text cursor to the start of the next line based on the current text size.
  • The carriage return character \r . This character will be ignored.

All other escaped characters will print the code page 437 character for the value that the escaped character evaluates to. \t (horizontal tab) evaluates to decimal (or hex) 09, which is a circle.

1 Like

Thanks @Pharap, another mystery solved :smiley: Aren’t you one of those famous British detectives?

1 Like

Bear in mind that the Arduboy’s default font is based on the code page 437 character set:

@Pharap Yes, but following the numbers they go from 0-9, then A-Z.
Codepage 437 has characters between 9 and A, so there’s still some difference.

I’m just starting to code.
What would be the reverse procedure?
To print out characters based on a number? Characters like this one : " " , or this one " "?

I am now :P

(I’d probably be a cross between DI Humphrey Goodman and DI Richard Poole. Grumpy, intelligent and eccentric in equal measure.)

There is no difference.
The axes are in hexadecimal, you need to compare to the hexadecimal column of the ASCII table.

For example, \a is BEL (bell) in the ascii table, which is 7 in hex, or more fully 0x07.
If you use that on the code page 437 table to take the first row (0_) and the 8th column (_7) then you get a dot, which is exactly what prints when you do arduboy.print('\a');.

If you haven’t got to grips with binary and hexadecimal yet, have a read of this:
https://www.mathsisfun.com/binary-number-system.html

And then just keep practising. Eventually it becomes second nature.
If you have trouble converting and you’re on Windows then you can use the Windows calculator, go to View > Programmer and you’ll get access to programmer mode which has a lot of common operations that programmers like to do.

I’m not sure what exactly you’re asking.

char c = static_cast<char>(65);
int i = static_cast<int>('A');

You have to find them in the code page 437 table (though I’m not sure the Arduboy implemented the whole of code page 437 so some might not be present).

Looking at the table the second one (╬) looks like C_, _E, or 0xCE so you’d do arduboy.print(static_cast<char>(0xCE));, or arduboy.print('\xCE');.

2 Likes

I believe code page 437 is implemented completely.

However, the implementation consists of characters that are 8 pixels high by 5 pixels wide. The write() (and thus print()) function adds an extra vertical single pixel space after the end of each character to separate them. This means that the line drawing characters from 0xB3 to 0xDA will not touch horizontally, as they are intended to. The font would have to be 8 x 6, with the spacing pixel included as part of each character itself, in order for this to work properly.

Also, the characters \n (0x0A, ◘) and \r (0x0D, ♪) cannot be displayed using write()/print() because they are handled specially, as mentioned previously.

1 Like

Just to be clear, it’d only shorten the source code. The actual resulting compiled binary would be identical.

2 Likes