strncpy 替换为 strncpy_s
时间: 2023-11-17 16:59:17 浏览: 170
strncpy_s是strncpy的安全版本,它始终确保目标缓冲区以空字符结尾,并且在缓冲区溢出时会触发运行时错误。因此,如果您需要在预定义的接口中使用strncpy功能,可以将其替换为strncpy_s以提高安全性。但是,如果您需要在长度超过1的字符串上使用strncpy_s,则需要注意返回值E_UNEXPECTED,因为它不会像strncpy一样截断字符串。
相关问题
解释一下这段代码void erase_wifi(char* ssid) { int i = 0; uint8_t is_wifi_exist = 0; if (NULL == ssid || 0 == strcmp(ssid, "")) { wifi_error("ssid is NULL or ssid empty"); goto exit; } for (i = 0; i < s_wifi_list->wifi_cnt; i++) { if (0 == strcmp(s_wifi_list->wifi_info[i].ssid, ssid)) { is_wifi_exist = 1; break; } } OS_MutexLock(&record_wifi_list_opt_mutex, OS_WAIT_FOREVER); if (!is_wifi_exist) { wifi_error("wifi [%s] not exist.", ssid); goto exit; } else { app_wifi_set_erase_wifi_info(s_wifi_list->wifi_info[i].ssid, s_wifi_list->wifi_info[i].pwd); strncpy(s_wifi_list->wifi_info[i].ssid, s_wifi_list->wifi_info[s_wifi_list->wifi_cnt - 1].ssid, MAX_SSID_LEN); strncpy(s_wifi_list->wifi_info[i].pwd, s_wifi_list->wifi_info[s_wifi_list->wifi_cnt - 1].pwd, MAX_PWD_LEN); memset(s_wifi_list->wifi_info[s_wifi_list->wifi_cnt - 1].ssid, 0, MAX_SSID_LEN); memset(s_wifi_list->wifi_info[s_wifi_list->wifi_cnt - 1].pwd, 0, MAX_PWD_LEN); if (s_wifi_list->wifi_cnt == WIFI_INFO_CNT) { s_wifi_list->write_idx = 9; } else { s_wifi_list->write_idx -= 1; } s_wifi_list->wifi_cnt -= 1; } #if CFG_USE_LFS _wifi_info_save_to_lfs(); #else _wifi_info_save(); #endif exit: OS_MutexUnlock(&record_wifi_list_opt_mutex); return; }
这段代码是一个函数,用于删除特定的Wi-Fi网络信息。函数接受参数ssid,表示要删除的Wi网络的名称。
首函数会检查参数的有效性。如果ssid为NULL或为空字符串会打印错误消息并跳转到末尾。
接下来,函数会遍存储Wi-Fi信息的s_wifi_list,查与参数ssid匹配的-Fi网络。如果找到了匹的网络,则将is_wifi_exist志设置为1,并循环。
在进入临界区之前,函数会使用互斥锁(OS_MutexLock)锁定对记录Wi-Fi列表进行操作的互斥访问。
如果is_wifi_exist标志为0,表示未找到与参数ssid匹配的Wi-Fi网络,则会打印错误消息并跳转到函数末尾。
如果找到了匹配的Wi-Fi网络,函数会使用app_wifi_set_erase_wifi_info函数设置要删除的Wi-Fi网络的信息,并将该网络信息替换为数组中最后一个Wi-Fi网络的信息。然后,将最后一个Wi-Fi网络的信息清空。
接下来,根据Wi-Fi网络信息的数量进行一些调整。如果当前Wi-Fi网络数量等于WIFI_INFO_CNT,则将write_idx设置为9;否则,将write_idx减1。然后,将Wi-Fi网络数量减1。
最后,根据预编译指令选择调用_wifi_info_save_to_lfs函数将Wi-Fi网络信息保存到LFS(Local File System)中,或调用_wifi_info_save函数将Wi-Fi网络信息保存到其他存储介质中。
最后,释放临界区的互斥锁(OS_MutexUnlock)并返回函数。
这段代码的作用是从Wi-Fi网络列表中删除指定的Wi-Fi网络信息,并将修改后的列表保存到存储介质中。
void ShowMessageLBJ(POCSAG_RESULT* POCSAG_Msg) { char LBJ_Info[3][7] = {{0},{0},{0}};、 for(uint8_t i = 0;i < 3;i++) { strncpy(LBJ_Info[i],POCSAG_Msg->txtMsg+i5,5); OLED_ShowString(68,0,LBJ_Info[0],16); OLED_ShowString(7*8,4,LBJ_Info[2],16); } 这个是STM32F103C8T6和ssd1306的显示函数,现在是收到消息直接显示,不会息屏,能不能帮我把它修改为收到消息后常亮6秒,如果有新消息就替换显示,不用HAL_GetTick
可以使用定时器来实现消息显示和替换的功能。具体做法是,在接收到新消息时,启动一个定时器,定时器到达后关闭屏幕,然后在新消息到达时重新启动定时器,以此循环。
下面是修改后的代码示例:
```
#define DISPLAY_TIME 6000 // 显示时间,单位为毫秒
TIM_HandleTypeDef htim3; // 定时器句柄
void StartDisplayTimer(uint16_t time)
{
HAL_TIM_Base_Start_IT(&htim3);
__HAL_TIM_SET_AUTORELOAD(&htim3, time);
}
void StopDisplayTimer()
{
HAL_TIM_Base_Stop_IT(&htim3);
OLED_Clear();
}
void ShowMessageLBJ(char* msg)
{
OLED_Clear();
OLED_ShowString(68, 0, msg, 16);
StartDisplayTimer(DISPLAY_TIME);
}
void ReceiveMessageLBJ(POCSAG_RESULT* POCSAG_Msg)
{
static char last_msg[16] = {0}; // 上次显示的消息
char LBJ_Info[3][7] = {{0},{0},{0}};
for (uint8_t i = 0; i < 3; i++)
{
strncpy(LBJ_Info[i], POCSAG_Msg->txtMsg + i * 5, 5);
}
char msg[16];
snprintf(msg, 16, "%s %s", LBJ_Info[0], LBJ_Info[2]);
if (strcmp(msg, last_msg) != 0)
{
strncpy(last_msg, msg, 15);
ShowMessageLBJ(msg);
}
else
{
StartDisplayTimer(DISPLAY_TIME);
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM3)
{
StopDisplayTimer();
}
}
```
这里使用了定时器来实现屏幕显示和关闭。在接收到新消息时,判断是否和上一次显示的消息相同,如果不同则调用`ShowMessageLBJ`函数显示新消息,否则重新启动定时器。在定时器到达时,调用`StopDisplayTimer`函数关闭屏幕。定时器的实现可以参考STM32 HAL库的定时器使用方法。
阅读全文