如何修改C语言指针数组内容?字符串转小写场景下数组初始化方法咨询
问题原因
你代码运行异常的核心原因是C语言规范中,直接用双引号定义的字符串字面值属于只读常量,存储在进程的只读数据段,修改该区域内存属于未定义行为,通常会直接触发段错误。你原写法中char * strings[5]的每个指针都指向这类只读字符串,因此无法修改内部字符。
解决方案
仅调整你指定的初始化行即可实现无需用户输入的可写字符串数组初始化,推荐以下两种简便方案:
- 方案一:使用二维字符数组存储(需同步修改转换函数的入参定义)
将初始化行修改为:
同时将char strings[5][10] = { "Pen", "Car", "Dev", "Lamp", "Noon" };convert函数的签名修改为:
该写法直接在栈上开辟连续的可写内存存储所有字符串,兼容性最好。void convert(char array[][10], int n) - 方案二:使用复合字面量初始化指针数组(无需修改其他代码,仅调整初始化行)
将初始化行修改为:
该写法利用C99引入的复合字面量特性,将每个字符串字面值拷贝到栈上的可写字符数组中,再将数组首地址赋值给指针数组元素,完全兼容原有其余代码逻辑。char * strings[5] = { (char[]){"Pen"}, (char[]){"Car"}, (char[]){"Dev"}, (char[]){"Lamp"}, (char[]){"Noon"} };
修改后可正常运行的完整代码(采用方案二)
#include <stdio.h> #include <stdlib.h> char v2m(char z) { if(z >= 'A' && z <= 'Z') return z += 32; else return z; } void convert(char ** array, int n) { for(int i = 0; i < n; i++) for(int j = 0; array[i][j] != '\0'; j++) array[i][j] = v2m(array[i][j]); } int main() { char * strings[5] = { (char[]){"Pen"}, (char[]){"Car"}, (char[]){"Dev"}, (char[]){"Lamp"}, (char[]){"Noon"} }; printf("Before: "); for(int i = 0; i < 5; i++) printf("\n%s", strings[i]); convert(strings, 5); printf("\nAfter: "); for(int i = 0; i < 5; i++) printf("\n%s", strings[i]); return 0; }
可选优化建议
- 大小写转换逻辑可以直接调用标准库
<ctype.h>中的tolower()函数,无需自行实现,对不同字符集的兼容性更强 - 数组长度可以通过
sizeof(strings)/sizeof(strings[0])动态计算,避免硬编码固定数值,后续增减字符串元素时无需同步修改遍历参数 - 指针数组的元素访问可以改用
array[i][j]的写法,和原有的(*(array + i))[j]逻辑完全等价,可读性更高
内容的提问来源于stack exchange,提问作者Edmond Dantes
相关产品推荐
相关产品推荐

