简体   繁体   中英

Passing a pointer (string) to a C function

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:

  • Is it correct to declare a string with uint16_t ?
  • What is recommended way to pass a string to a function?

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 (eg 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 (ie 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:

  • Rather than using 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 .
  • Wide character literals must start with an L prefix.
  • Rather than using printf , you need to use wprintf .
  • In the format string, use %ls rather than %s . ( Unless you use Microsoft's compiler .)

Finally, some less grave errors:

  • As noted, T * const arguments are useless. The author probably meant T const * (or equivalently const T * ).
  • You can remove <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.

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.

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".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM