char stuff[100]; // not initialized
stuff[0] = '\0'; // first character is now the null terminator,
// so 'stuff' is effectively ""
strcpy(stuff, "hi "); // this initializes 'stuff' if it's not already.
// AddToArray help:
//
// In the beginning you must initialize ArrCurrIdx to zero during the first call:
// uint8_t ErrorArr8[255]; memset(ErrorArr8, 0, 255); // add '\0
// then first call:
// if(!AddToArray(ErrorArr8, tmp)) return 0; // overflow
//
// Arr is an array where we need to put the data
// AddedArr is an added array
// AddToArray is an analog of strcat() with added overflow protect
uint8_t AddToArray(uint8_t * Arr, uint8_t * AddedArr)
{
static uint8_t ArrCurrIdx = 0;
uint16_t ArrLen = strlen((const char*)Arr);
uint16_t AddedLen = strlen((const char*)AddedArr);
if(ArrLen == 0) // initialize ArrCurrIdx to zero during the first call
{
memset(Arr, 0, 255);
ArrCurrIdx = 0;
}
if((ArrCurrIdx + AddedLen) > 255 ) // 255 is max Arr size
{
uint8_t tmp[] = "OVERFLOW in AddToArray\n\r"; //
memcpy(&Arr[0], tmp, strlen((const char*)tmp));
return 0; // to prevent overflow
}
memcpy(&Arr[ArrCurrIdx], AddedArr, AddedLen);
ArrCurrIdx = ArrCurrIdx + AddedLen;
return 1;
}
// Example:
// 1.
// uint8_t ErrorArr8[255];
// memset(ErrorArr8, 0, 255); // To set ArrCurrIdx to zero
// uint8_t tmp[] = "Error message or message 1. ";
// if(!AddToArray(ErrorArr8, tmp)) return 0; // if 0 then overflow;
//
// uint8_t tmp11[] = "Next message. ";
// if(!AddToArray(ErrorArr8, tmp11)) return 0; // if 0 then overflow;
//
// uint8_t tmp22[] = "Then another added message. ";
// if(!AddToArray(ErrorArr8, tmp22)) return 0; // if 0 then overflow;
//
// // We start new cycle:
// uint8_t a[20];
// memset(a, 0, 20); // To set ArrCurrIdx to zero
// uint8_t tmp33[] = "Brand new error message or message. ";
// if(!AddToArray(a, tmp33);)) return 0; // if 0 then overflow;
// 2.
// if(!AddToArray(ErrorArr8, "\n\r")) return 0; // if 0 then overflow; will automatically append \0 to "\n\r"
/********************************************************************************************************************************************/
// uint8 transform to uint8_t is analog of atoi
uint8_t* ui8toa(uint8_t i)
{
static uint8_t arr[4]; // fourth digit is for '\0'
memset(arr, 0, 4); // 0 equals '\0' because '\0' and 0 are stored as 0.
sprintf((char*)arr, "%u", i);
return arr;
}
//Example:
// if(!AddToArray(ErrorArr8, ui8toa(i))) return 0; // if 0 then overflow
/********************************************************************************************************************************************/
6条答案
按热度按时间wyyhbhjk1#
strcat
将查找空终止符,将其解释为字符串的结尾,并在那里追加新的文本,在此过程中覆盖空终止符,并在串联的结尾处写入新的空终止符。字符串
空终止符在哪里?
stuff
未初始化,因此它可能以NUL开头,也可能没有NUL。在C++中,你可以这样做:
型
现在可以执行strcat了,因为'stuff'的第一个字符是空终止符,所以它会追加到正确的位置。
在C中,你仍然需要初始化'stuff',这可以通过以下几种方式完成:
型
pengsaosao2#
在第一种情况下,
stuff
包含垃圾。strcat
要求目标和源都包含正确的空终止字符串。字符串
将扫描
stuff
以查找终止字符'\0'
,并从该字符开始复制"hi "
。如果它没有找到它,它将从数组的末尾运行,并且可能会发生任何不好的事情(即,行为未定义)。避免这个问题的一个方法是这样的:
型
也可以将
stuff
初始化为空字符串:型
这将用零填充
stuff
的所有100个字节(增加的清晰度可能值得任何小的性能问题)。w6lpcovy3#
因为
stuff
在调用strcpy
之前未初始化。在声明stuff
不是空字符串之后,它是未初始化的数据。strcat
将数据追加到字符串的末尾-也就是说,它在字符串中找到空终止符并在其后添加字符。一个未初始化的字符串不能保证有一个null终止符,所以strcat
很可能会崩溃。如果要初始化
stuff
,如下所示,您可以执行strcat:字符串
ttvkxqim4#
Strcat将字符串追加到现有字符串。如果字符串数组为空,则不会查找字符串结尾(
'\0'
),并且会导致运行时错误。根据Linux手册页,简单的strcat是这样实现的:
字符串
正如您在这个实现中看到的,
strlen(dest)
将不会返回正确的字符串长度,除非将dest
初始化为正确的c字符串值。你可能很幸运地在char stuff[100];
处有一个第一个值为零的数组,但你不应该依赖它。kjthegm65#
另外,我建议不要使用
strcpy
或strcat
,因为它们可能会导致一些意想不到的问题。使用
strncpy
和strncat
,因为它们有助于防止缓冲区溢出。oiopk7p56#
可能更安全:
字符串
/********************************************************************************************************************************************/
型