Reputation: 327
Please read until the end before you say: "Oh no, this question again..."
I am right now seating in a C course and the following example has been provided in course book:
#include <stdio.h>
#include <stdint.h>
void Terminal_PrintData(uint16_t * const Data);
int main(void){
uint16_t StringData[] = "MyData";
Terminal_PrintData(StringData);
}
void Terminal_PrintData(uint16_t * const Data)
{
printf("Value: %s", *Data);
}
When I compile this masterpiece, this is what I get:
F:\AVR Microcontroller>gcc -o test test.c
test.c: In function 'main':
test.c:7:26: error: wide character array initialized from non-wide string
uint16_t StringData[] = "MyData";
My questions are:
uint16_t
?Upvotes: 0
Views: 2632
Reputation:
Your immediate questions:
- Is it correct to declare a string with uint16_t?
No.
All strings are always char[]
. There ar also wide strings (strings of wide characters), which have the type wchar_t[]
, and are written with an L
prefix (e.g. L"hello"
).
- What is recommended way to pass a string to a function?
As a pointer to the first character in the string, so either char *
or wchar_t *
. The const
qualifier makes no sense here; it would mean that the pointer (not the string itself) is constant (see here). I'd recommend writing wchar_t const *
or const wchar_t *
instead; it has a different meaning (i.e. the string can't be changed), but it's correct and meaningful.
You mention that this code is from a course book. I'm not sure whether you mean that these are lecture notes handed out by your professor, or whether you bought a published book. In either case, if this snippet is representative of the quality of the book/notes, get a refund.
For now, let's make this code work.
There's an error in this code that will cause the program to crash:
printf("... %s ...", ..., *string, ...)
when string
is a char*
is always wrong. Don't dereference that pointer.If you insist on using "wide" characters (which is questionable), you're going to have to change a few things:
char
, you need to include <wchar.h>
and use wchar_t
instead. As far as I know, uint16_t
and uint8_t
won't work unless you use explicit casting everywhere. That's because char
doesn't have 8 bits, but CHAR_BIT
bits.L
prefix.printf
, you need to use wprintf
.%ls
rather than %s
. (Unless you use Microsoft's compiler.)Finally, some less grave errors:
T * const
arguments are useless. The author probably meant T const *
(or equivalently const T *
).<stdint.h>
and <stdio.h>
. We're no longer using uint16_t
, and <wchar.h>
declares some wide character <stdio.h>
-like functions.I end up with the following code:
#include <wchar.h>
void Terminal_PrintData(wchar_t const * Data);
int main(void){
wchar_t StringData[] = L"MyData";
Terminal_PrintData(StringData);
}
void Terminal_PrintData(wchar_t const * Data)
{
wprintf(L"Value: %ls", Data);
}
This compiles and runs as expected with both GCC and Clang on Linux x86-64.
Upvotes: 6
Reputation: 91149
There are two kinds of strings: "non-wide" ones which consist of char
s and "wide" ones which consist of wchar_t
s and are written as L""
(single wchar_t
s can be written as L''
). There are functions to convert between them; apart from these, you cannot intermix them.
Depending on the system, a wchar_t
can be 16 or 32 bits wide.
Upvotes: 3
Reputation: 593
You should view your string as an array of characters (in this case, 8-bit characters) so a uint8_t would suffice. What you normally do is pass the beginning of the string (which is the pointer to the array) to your function. To make it safer, you could also pass the length of the string as an argument, but normally your string will end with a delimiter (\0).
when you pass stringData
to your function, you're actually saying &stringData[0]
, literally "the address (&) of the first element ([0]) of the array".
Upvotes: 0