使用sprintf()函数后,C char字符串不可读

时间:2017-11-30 12:55:03

标签: c string printf arduino-uno arduino-ide

在Arduino Sketch上我需要使用C Strings而不是C ++ String对象来减少内存使用。这本身就是一个挑战,因为我不熟悉经典C。

然而不知怎的,我让它工作(或多或少),但我遇到了一个问题。这是一个测试草图来解释它:

#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() {


}

如果我要取消注释

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

然后我无法在串行监视器上打印foo,也无法打印稍后生成的新foo。如果我硬编码整数而不是strlen()函数,情况也是如此。

我会将此描述为一种奇怪的行为,但很可能只是我自己的无知。我阅读了有关sprintf()方法的文档,但我没有看到有关此问题的任何内容。

任何帮助将不胜感激。 提前谢谢!

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:3)

好吧,似乎foo(很大的变量名称,btw)的长度可以超过99,所以你需要超过两位数。你知道C字符串是0终止的吗?字符串"123"的内存中表示形式为:

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

其中\0char,其值为0.因此,总是需要一个额外的位置来保存它。你应该让你的阵列更大:

char numberString[8];

要安全起见。使用snprintf()也有帮助:

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

因为技术上你也会从类型不匹配中获得未定义的行为(%d用于int,但strlen()返回size_t)。

答案 2 :(得分:1)

您为numberString保留了3个字符。这包括终止零字符。如果strlen(foo)返回一个大于99的整数,则会溢出numberString缓冲区。缓冲区溢出后,可能会发生有趣的事情。

答案 3 :(得分:1)

strlen()上的问题不会给出以空字符结尾的字节长度。

  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));