C语言实现结构体name字段缓冲区保护,要求使用strncpy/strncmp
问题解决方案
问题根因
- 结构体
_data的name字段是长度为5的char数组,最多只能存4个有效字符+1个终止符,原有代码在加载数据时注释了手动加终止符的逻辑,可能导致name字段不是合法C字符串,出现未定义行为。 - 搜索逻辑只比较前5个字符,没有对用户输入的搜索参数长度做校验,只要前5个字符匹配就会返回命中,即使用户输入的名称长度远超5字符,也会错误返回匹配结果。
修改步骤
1. 修复数据加载逻辑,保证name字段为合法字符串
在LOAD函数中放开终止符赋值的注释,确保不管读取的名称多长,存储的name都以\0结尾,且有效长度不超过4,全程使用要求的strncpy:
strncpy(BlackBox[i].name, name, 5); BlackBox[i].name[4] = '\0'; // 取消这行的注释
2. 优化搜索逻辑,增加长度校验
在SEARCH函数中先判断用户传入的搜索名称长度,如果超过4(因为数组长度5,最多存4个有效字符)直接判定为无匹配;同时使用要求的strncmp调整比较逻辑保证完全匹配:
void SEARCH(struct _data *BlackBox, char *name, int counter) { int i; int found = 0; // 新增长度校验:搜索名长度超过4直接不匹配 if(strlen(name) > 4) { printf("*******************************************\n"); printf("The name was NOT found.\n"); printf("*******************************************\n"); return; } for (i = 0; i < counter; i++) { // 比较长度取搜索名长度+1,保证包含终止符的完全匹配 if (!strncmp(name, BlackBox[i].name, strlen(name)+1)) { printf("************************************************ \n"); printf("[%s] was found at the %d entry.\n",name, i); printf("************************************************* \n"); found = 1; break; } } if (found == 0) { printf("*******************************************\n"); printf("The name was NOT found.\n"); printf("*******************************************\n"); } }
3. 可选优化:修正main函数参数名笔误
原有main函数的参数名写反了,属于行业通用笔误,可修改提升代码可读性:
// 原写法:int main(int argv, char **argc) int main(int argc, char **argv) { int size; FILE *data; struct _data *BlackBox; if (argc == 1) { printf("*******************************************\n"); printf("* You must include a name to search for. *\n"); printf("*******************************************\n"); } if (argc == 2) { size = SCAN(&data); BlackBox = LOAD(data, size); SEARCH(BlackBox, argv[1], size); FREE(BlackBox, size); } return 0; // 正常退出建议返回0 }
效果验证
- 传入长度≥5的搜索参数时,会直接返回未找到,符合需求。
- 传入长度≤4的参数时,会和存储的名称做完全匹配,不会出现部分匹配的错误。
- 存储的
name字段永远带终止符,避免缓冲区溢出和字符串操作的未定义行为。
内容的提问来源于stack exchange,提问作者jtmopao
相关产品推荐
相关产品推荐

