简体   繁体   中英

C char string not readable after using sprintf() function

On an Arduino Sketch I need to use C Strings instead of C++ String objects in order to minimize memory usage. This has been a challenge in itself as I'm not familiar with classic C.

However somehow I got it to work (more or less) but I'm encountering a problem. Here is a test Sketch to explain it:

#define APIKEY "TWITTER_KEY" //  api key ThingSpeak
#define TARGET_IP "184.106.153.149"///         //local  direccion IP o Hosting  ThingSpeak
#define TARGET_PORT "80"          ///  puerto 80
#define ID "WiFi_ID"  //name of wireless access point to connect to   - Red de inhalambrica wifi 
#define PASS "WiFI_Password"  //wifi password                          - Contraseña de Wifi 



#define TWEET "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."


char foo[400]; //contains the tweet request
char bar[20]; //auxiliary
char numberString[3]; //contains numbers


void setup() {

  Serial.begin(9600);

  testMethod();

}


void testMethod(){

   Serial.println(" ");
   Serial.println("testMethod");
   Serial.println(" ");



    strcpy(foo, "api_key=");
    strcat(foo, APIKEY);
    strcat(foo, "&status=");
    strcat(foo, TWEET);

    Serial.println(foo);


  //sprintf(numberString, "%d", strlen(foo)); //converts the integer into a char


  Serial.println(numberString);


     // Create HTTP POST Data  


     strcpy(foo, "POST /apps/thingtweet/1/statuses/update HTTP/1.1\n");
     strcat(foo, "Host: api.thingspeak.com\n");
     strcat(foo, "Connection: close\n");
     strcat(foo, "Content-Type: application/x-www-form-urlencoded\n");
     strcat(foo, "Content-Length: ");
     strcat(foo, numberString);
     strcat(foo, "\n\n");
     strcat(foo, "api_key=");
     strcat(foo, APIKEY);
     strcat(foo, "&status=");
     strcat(foo, TWEET);


    Serial.println(foo);


  }




void loop() {


}

If I am to uncomment out the line

 //sprintf(numberString, "%d", strlen(foo)); //converts the integer into a char

then I am not able to print foo on the serial monitor nor I am able to print the new foo generated later on. The same is true if I hard code an integer instead of the strlen() function.

I would describe this as a bizarre behavior, but most probably is just plain ignorance from my part. I read the documentation about the sprintf() method, but I haven't seen anything regarding this issue.

Any help will be much appreciated. Thanks in advance!

strlen(foo)是3位数字,因此您需要为numberString分配4个字节以适合这3位数字和NUL终止符。

Well, it seems the length of foo (great variable name there, btw) can be more than 99, so you need more than two digits. You do know that C strings are 0-terminated right? The in-memory representation of the string "123" is:

+-+-+-+--+
|1|2|3|\0|
+-+-+-+--+

where \\0 is a char with the value 0. So one extra location is always needed to hold that. You should make your array larger:

char numberString[8];

to be on the safe side. Also using snprintf() had helped here:

snprintf(numberString, sizeof numberString, "%zu", strlen(foo));

since technially you're getting undefined behavior from the type mis-match, too ( %d is for int , but strlen() returns size_t ).

You have reserved 3 characters for the numberString. That includes the terminating zero character. If strlen(foo) returns an integer that is greater than 99, you will overflow numberString buffer. After the buffer overflow funny things may happen.

You have the problem on strlen() which doesn't give null-terminated byte length.

  char foo[400] = "hello world";
 // here you allocated the less width, in  C strings are the sequence of character bytes terminated with NULL in the end.
  char number[4]; 

  sprintf(number, "value: %zu\n", strlen(foo));

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