在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()
方法的文档,但我没有看到有关此问题的任何内容。
任何帮助将不胜感激。 提前谢谢!
答案 0 :(得分:3)
strlen(foo)
是一个3位数字,因此您需要为numberString
分配4个字节以适合这3个数字和NUL终结符。
答案 1 :(得分:3)
好吧,似乎foo
(很大的变量名称,btw)的长度可以超过99,所以你需要超过两位数。你知道C字符串是0终止的吗?字符串"123"
的内存中表示形式为:
+-+-+-+--+
|1|2|3|\0|
+-+-+-+--+
其中\0
是char
,其值为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));