C语言中如何将字符数组的每行分别复制到字符数组构成的数组中?
问题分析与修正方案
你的代码出现不可预测结果,主要是以下几个问题导致的:
- 缺少字符串终止符:C风格字符串必须以
\0结尾,你只复制了每行的字符,没有在每行末尾添加终止符,后续读取这些字符串时会越界读取内存中的随机数据,引发异常。 - 使用非标准变长数组(VLA):C++标准不支持
char tmpcstr[numlines][len];这种变长数组,虽然部分编译器提供扩展支持,但会导致可移植性问题,且如果len或numlines较大,容易触发栈溢出。 - 未处理行索引越界:如果输入字符串中的换行符数量超过
numlines-1,line++会让行索引超出数组范围,导致数组越界访问,触发未定义行为。 - 未处理最后一行无换行符的情况:若输入的最后一行没有以
\n结尾,该行字符串不会被终止,同样会导致读取异常。
修正后的代码(推荐使用C++容器)
用std::vector管理内存,避免栈溢出和手动内存管理的麻烦:
#include <vector> void TempControl::show_status_lines(const char *tmpc, int numlines) { std::vector<std::vector<char>> tmpcstr(numlines); int line = 0; for (int i = 0; tmpc[i] != '\0' && line < numlines; ++i) { if (tmpc[i] != '\n') { tmpcstr[line].push_back(tmpc[i]); } else { // 添加字符串终止符 tmpcstr[line].push_back('\0'); ++line; } } // 处理没有以换行结尾的最后一行 if (line < numlines && !tmpcstr[line].empty()) { tmpcstr[line].push_back('\0'); } for (int i = 0; i < numlines; ++i) { if (!tmpcstr[i].empty()) { // 输出或处理 tmpcstr[i].data() } } }
若坚持使用C风格动态数组
如果必须用C风格数组,需手动管理内存并避免越界:
void TempControl::show_status_lines(const char *tmpc, int numlines) { int len = strlen(tmpc); // 动态分配行指针数组,初始化为nullptr char **tmpcstr = new char*[numlines](); int line = 0; int j = 0; // 为第一行分配内存(预留终止符位置) if (numlines > 0) { tmpcstr[line] = new char[len + 1]; } for (int i = 0; i < len && line < numlines; ++i) { if (tmpc[i] != '\n') { tmpcstr[line][j++] = tmpc[i]; } else { tmpcstr[line][j] = '\0'; ++line; j = 0; if (line < numlines) { tmpcstr[line] = new char[len + 1]; } } } // 处理最后一行 if (line < numlines && tmpcstr[line] != nullptr) { tmpcstr[line][j] = '\0'; } for (int i = 0; i < numlines; ++i) { if (tmpcstr[i] != nullptr) { // 输出或处理 tmpcstr[i] } } // 释放内存,避免泄漏 for (int i = 0; i < numlines; ++i) { delete[] tmpcstr[i]; } delete[] tmpcstr; }
内容的提问来源于stack exchange,提问作者nayyytan
相关产品推荐
相关产品推荐

