C++表达式未执行:逐行读取字符串函数异常求助
我写了一个简单的函数,接收string类型的参数code,想按行读取内容(行分隔符定义为TERMINATOR,当前是'\n'),代码如下:
uint16_t* compile(string code){ for(int i = 0; i < code.length(); i++){ string line; while(code[i] != TERMINATOR){ char c = code[i]; string s(1,c); line.append(s); i++; } printf("%s\n", line); } }
调用方式是:compile("asdf\nasfgh\nafefsfs\n");,但执行到char c = code[i];时,变量c始终为0(已经用gdb验证过),程序每次运行都会输出乱码,每次会输出三个随机的5字符,求帮忙解决!
问题分析与解决方案
咱们一步步拆解你代码里的问题:
越界访问导致未定义行为
你的while循环会一直递增i直到遇到TERMINATOR,但当i达到code.length()时,code[i]属于越界访问(std::string的有效下标范围是0到length()-1)。这时候访问的是字符串末尾之外的内存,值完全不确定——也就是你看到c始终为0的原因,甚至可能触发更严重的程序崩溃。printf参数类型不匹配导致乱码
printf("%s\n", line);里的line是std::string对象,而%s格式符要求传入const char*类型的指针。直接传string对象会把它的内部结构当成char指针解析,这必然会输出乱码。正确的做法是调用line.c_str()来获取标准C风格字符串指针。函数返回值不符合声明要求
函数声明返回uint16_t*,但你的函数里没有任何return语句,这会导致未定义行为,程序的执行状态完全不可预测。如果这个函数不需要返回值,应该把返回类型改成void。未处理最后一行无换行符的情况
如果输入的字符串最后一行没有TERMINATOR,你的循环会直接越界,无法读取最后一行内容。
修正后的代码
#include <string> #include <cstdio> #define TERMINATOR '\n' void compile(const std::string& code){ // 改为void返回,用const引用避免不必要的拷贝 size_t i = 0; // 用size_t更合适,和string::length()的返回类型匹配 const size_t len = code.length(); while(i < len){ std::string line; // 循环到行尾或者字符串结束,避免越界 while(i < len && code[i] != TERMINATOR){ line += code[i]; // 简化字符追加写法,比临时string+append更高效 i++; } // 跳过换行符(如果还没到字符串末尾) if(i < len){ i++; } printf("%s\n", line.c_str()); // 用c_str()获取符合printf要求的const char* } } // 调用示例 int main(){ compile("asdf\nasfgh\nafefsfs\n"); return 0; }
关键改进点
- 把返回类型改成
void,消除无返回值导致的未定义行为 - 使用
size_t类型下标,和string::length()的返回类型匹配,避免类型不匹配隐患 - 在while循环中增加
i < len的判断,彻底杜绝越界访问 - 简化字符追加逻辑,直接用
line += code[i],提升代码简洁性和效率 - 调用
line.c_str()传给printf,确保格式符与参数类型严格匹配 - 处理了最后一行无换行符的场景,保证所有内容都能被正确读取
这样修改后,你的代码就能正确按行读取字符串并输出,不会再出现乱码和变量异常的问题了。
内容的提问来源于stack exchange,提问作者James B. Reese

