Trying to split string into several lines:
const char* d = "aaa\
bbb";
This brings aaa\t\tbbb because code formatting brought two tab's before bbb.
If I remove tab's I have nice aaabbb string.
const char* d = "aaa\
bbb";
How to leave code formatting but do not put tab's in string.
Consecutive strings constants separated by whitespace are automatically concatenated by the compiler. So you can do this:
const char* d = "aaa"
"bbb";
Related
I am building an avr program with many wchar_t strings. At the moment the way I store them in to the chip is this:
const _flash wchar_t* const Greek_text[] =
{
[ACCELERATION_TEXT] = (const _flash wchar_t[]) {L"Επιταγχυνση"},
[ACCELERATION_SHORT_TEXT] = (const _flash wchar_t[]) {L"Επιταγχ."},
[REDUCED_TEXT] = (const _flash wchar_t[]) {L"Μειωμενη"},
[FULL_TEXT] = (const _flash wchar_t[]) {L"Μεγιστη"}
}
I am looking for a way to store them while being compressed. One way that I can think of, is removing the Unicode prefix for the specific language, but the only way of doing this to my knowledge, is storing the lower half of each word manually in unsigned chars. Is there a more practical way of doing something like this?
It looks like all your strings are Greek. You could assign each letter or character that appears in your strings to a number between 1 and 255 and then just have char strings where each char contains one of those encoded numbers. This would halve the space of each individual string, but you might need a lookup table in your program to convert those codes back to unicode, and that table could occupy up to 512 bytes in your program memory depending on how many different characters you use.
People have already developed encodings like this before, so maybe you could just use a standard one, like Windows-1253.
Figuring out a good system to author these encoded strings and insert them into your program is another challenge. I'd suggest writing a simple Ruby program like the one below. (You'd save the program itself as a UTF-8 text file on your computer and edit it using a standard text editor.)
string_table = {
ACCELERATION_TEXT: 'Επιταγχυνση',
ACCELERATION_SHORT_TEXT: 'Επιταγχ.',
REDUCED_TEXT: 'Μειωμενη',
FULL_TEXT: 'Μεγιστη',
}
string_table.each do |key, value|
hex = value.encode('Windows-1253').each_byte.map { |b| '\x%02x' % b }.join
puts "[#{key}] = \"#{hex}\","
end
The program above outputs this:
[ACCELERATION_TEXT] = "\xc5\xf0\xe9\xf4\xe1\xe3\xf7\xf5\xed\xf3\xe7",
[ACCELERATION_SHORT_TEXT] = "\xc5\xf0\xe9\xf4\xe1\xe3\xf7\x2e",
[REDUCED_TEXT] = "\xcc\xe5\xe9\xf9\xec\xe5\xed\xe7",
[FULL_TEXT] = "\xcc\xe5\xe3\xe9\xf3\xf4\xe7",
Also, another way to maybe save space (while increasing CPU time used) would be to get rid of the array of pointers you are creating. This would save two bytes per string. Just store all the strings next to each other in memory. The strings would be separated by null characters and you can optionally have a double null character marking the end of the table. To look up a string in the table, you start reading bytes from the beginning of the table one at a time and count how many null characters you have seen.
const _flash char greek_text[] =
"\xc5\xf0\xe9\xf4\xe1\xe3\xf7\xf5\xed\xf3\xe7\0"
"\xc5\xf0\xe9\xf4\xe1\xe3\xf7\x2e\0"
"\xcc\xe5\xe9\xf9\xec\xe5\xed\xe7\0"
"\xcc\xe5\xe3\xe9\xf3\xf4\xe7\0";
If the following is a one byte array:
char arr[] = "\xFF";
If we do the following:
char arr[] = "\xFFmyrandomstringappendedafterbyte";
printing it would result in this:
byteValueGoesHEREmyrandomstringappendedafterbyte
However, if I try to do the following:
char arr[] = "\xFF98";
It will result in a warning:
warning: hex escape sequence out of range
It treats 98 as part of the hexcode. However, I would it to be treated as a string (as is myrandomstringappendedafterbyte).
I would like to have this as output byteValueGoesHERE98.
How can this be achieved without a whitespace? How can I denote that 98 should be treated as a string?
When string literals have only whitespace (or nothing) between them, the preprocessor combines them into a single string literal, but this does not "merge" escape sequences. So you can just write your desired string using two strings:
char arr[] = "\xFF" "98";
This is four bytes including the terminating '\0'.
I am trying to find the best way of getting an input of string without the spaces and tabs.
And from it to get dynamic number of the individual strings that the main one contian.
For example:
For the string str = " abc \t tt 6 \t 4 7"
(There can be a lot more spaces and tabs between the individual strings)
The out put will be str1 = "abc" str2 = "tt" str3 = "6" str4 = "4" str5 = "7"
I thought maybe for the dynamic creation of string to use malloc to creat an array of strings. But I could not make it work, and ignore the spaces and tabs (\t)
have a look to strtok() and strtok_r() functions from string.h
It allows you to split a string by specifying which characters are delimiters.
I have an array with one element, words in array are separated by tab (tab-key):
cli::array<String^> ^ PnkFld = {"Good bye cruel world"};
and program output should look like this with words being split in separate elements:
cli::array<String^> ^ PnkFld = {"Good","bye","cruel","world"};
You want the String::Split method. If you don't specify any parameters, you'll get this overload, which splits on whitespace when the parameter contains no characters.
I have been trying to understand macro expansion and found out that the second printf gives out an error. I am expecting the second print statement to generate the same output as the first one. I know there are functions to do string concatenation. I am finding it difficult to understand why first print statement works and the second doesn't.
#define CAT(str1, str2) str1 str2
void main()
{
char *string_1 = "s1", *string_2 = "s2";
printf(CAT("s1", "s2"));
printf(CAT(string_1, string_2));
}
Concatenating string literals, like "s1" "s2", is part of the language specification. Just placing two variables next to each other, like string_1 string_2 is not part of the language.
If you want to concatenate two string variables, consider using strcat instead, but remember to allocate enough space for the destination string.
Try to do the preprocessing "by hand":
CAT is supposed to take 2 input variables, and print them one after the other, with a space between. So... if we preprocess your code, it becomes:
void main()
{
char *string_1 = "s1", *string_2 = "s2";
printf("s1" "s2");
printf(string_1 string_2);
}
While "s1" "s2" is automatically concatenated to "s1s2" by the compiler, string_1 string_2 is invalid syntax.