简体   繁体   English

Itoa 阻止 strcat 正确附加

[英]Itoa stopping strcat from properly appending

I am trying to append a series of char arrays in Arduino C++.我正在尝试 append Arduino ZF6F87C9FDCF8B3C3F07F93F1EE8712 中的一系列字符 arrays I have a char array "outputString", and a series of other char arrays that I with to append with via strcat.我有一个字符数组“outputString”,以及一系列其他字符 arrays,我通过 strcat 与 append 一起使用。 I also have a checkSum generator that generates the checksum and I used Itoa to convert the checksum value from an int into a base16 character array for appending.我还有一个生成校验和的校验和生成器,我使用 Itoa 将校验和值从 int 转换为 base16 字符数组以进行附加。 This is what it looks like:这是它的样子:

char cmdtype[6] = "AAAAA"; //The 5-letter command
bool canPrint = true;

int checkSumGenerator(char message[]) {
  int checkSum = 0;
  for (int i = 0; i < 21; ++i)  //Remove the Checksum character, as well as the Null Character
  {
    checkSum ^= message[i];
  }
  Serial.println(checkSum);
  Serial.println("Printed checksum.");
  return checkSum;
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); // usb port serial
}

void loop() {
  //Collect data.
  if (Serial.available() > 0 && canPrint == true) {
    char outputString[] = "TOSBC_";
    Serial.println(outputString);
    
    strcat (outputString, cmdtype);
    Serial.println(outputString);
    strcat (outputString, "_");
    Serial.println(outputString);
    strcat (outputString, "00001212");
    strcat (outputString, "_");
    Serial.println("Line w/ "00001212" should be below");
    Serial.println(outputString);

    int outputCheckSum = checkSumGenerator(outputString);
    char outputCheckSumHex[3];
    itoa (outputCheckSum, outputCheckSumHex, 16); //Commenting this line seems to remove the "00001212" thing.

    Serial.println(outputCheckSum);
    //Serial.println(outputCheckSumHex);

    Serial.println(outputString);
    canPrint = false; //Only want it to print once.

  }
}

Under this code, the output is the following:在此代码下,output 如下:

10:40:23.740 -> TOSBC_
10:40:23.740 -> TOSBC_AAAAA
10:40:23.740 -> TOSBC_AAAAA_
10:40:23.740 -> Line w/ cmdparam should be below
10:40:23.740 -> TOSBC_AAAAA_00001212_
10:40:23.740 -> 87
10:40:23.740 -> Printed checksum.
10:40:23.740 -> 87
10:40:23.740 -> TOSBC_A57   //What I'm expecting is "TOSBC_AAAAA_00001212_57"

I am not entirely sure why that is the case.我不完全确定为什么会这样。 I don't know how itoa could possibly affect strcat from working properly, but this is something else I tried, and doing so allowed "00001212" to be printed.我不知道 itoa 可能如何影响 strcat 正常工作,但这是我尝试过的其他方法,这样做可以打印“00001212”。

int outputCheckSum = checkSumGenerator(outputString);
char outputCheckSumHex[3];
//itoa (outputCheckSum, outputCheckSumHex, 16); //Commenting this line seems to remove the "00001212" problem.

The output is: output 是:

10:43:29.178 -> TOSBC_
10:43:29.178 -> TOSBC_AAAAA
10:43:29.178 -> TOSBC_AAAAA_
10:43:29.178 -> Line w/ '00001212' should be below
10:43:29.178 -> TOSBC_AAAAA_00001212_
10:43:29.178 -> 87
10:43:29.178 -> Printed checksum.
10:43:29.178 -> 87
10:43:29.178 -> TOSBC_AAAAA_00001212_

Directly providing a value for outputCheckSum, like so, is also something I tried.像这样直接给 outputCheckSum 提供一个值,也是我尝试过的。 It did not fix the problem.它没有解决问题。

int outputCheckSum = 87;
char outputCheckSumHex[3];
itoa (outputCheckSum, outputCheckSumHex, 16); 

Please let me know if more information is required to solve this issue.如果需要更多信息来解决此问题,请告诉我。

The char outputString[] = "TOSBC_"; char outputString[] = "TOSBC_"; declaration gives the array just enough space to hold the initializer string;声明为数组提供了足够的空间来保存初始化字符串; that is, the size of the array will be determined from the number of elements in the string literal – which will 7 (the 6 visible characters plus a nul terminator).也就是说,数组的大小将由字符串字面量中的元素数决定——这将是 7(6 个可见字符加上一个nul终止符)。

Thus, attempting any strcat() on that will overflow the array's bounds and, as such, will be undefined behaviour (UB).因此,尝试任何strcat()都会溢出数组的边界,因此将是未定义的行为 (UB)。

The fact that problems don't appear immediately (ie after the first few calls to strcat ) is just one of the many possible manifestations of the UB.问题不会立即出现(即在最初几次调用strcat之后)这一事实只是 UB 的许多可能表现之一。 What appears to be happening, in your case, is that the compiler has assigned the memory for the outputCheckSumHex array right after that for outputString , and your call to ltoa is thus overwriting what has (by unlucky chance) already been written there by the earlier – and invalid – calls to strcat .在您的情况下,似乎正在发生的事情是,编译器在outputString之后立即为outputCheckSumHex数组分配了 memory ,因此您对ltoa的调用将覆盖之前已经写入的内容(不幸的是) -并且无效- 调用strcat

The fix is trivial: just declare the outputString array with an explicitly specified size, and one that will make it large enough to accommodate all possible appended strings:修复很简单:只需使用明确指定的大小声明outputString数组,并使其大到足以容纳所有可能的附加字符串:

  if (Serial.available() > 0 && canPrint == true) {
    char outputString[100] = "TOSBC_"; // Specify a big enough size here!
    Serial.println(outputString);
    //...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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