C++ substr截取字符串结果末尾带多余引号的问题
问题根本原因
核心错误是对C++ std::string::substr的参数语义理解偏差:substr(起始下标, 截取长度)的第二个参数代表从起始位置开始,要取的字符总个数,不是截取的结束位置下标,这是非常常见的接口误用。
我们可以把读入的字符串id="123456789"按索引拆解开(索引从0开始计数):
- 字符序列:
i d = " 1 2 3 4 5 6 7 8 9 " - 对应索引:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 - 字符串总长度为14。
逐行拆解你的代码逻辑:
s.find("\"")会找到第一个双引号,位置在索引3,+1后子串起始位置为4,正好对应第一个数字1,这部分逻辑没有问题。- 你传入的截取长度是
s.length()-1 = 13,也就是要从索引4开始连续取13个字符。但从索引4到字符串末尾一共只有10个字符(总长度14减去前4个字符),这种情况下substr不会报越界错误,会直接截取到字符串末尾,最终取到的就是索引4到13的所有字符:123456789",正好是你看到的带多余末尾引号的输出。
你把参数改成s.length()-5时,传入的截取长度是9,刚好匹配9位数字的长度,所以能得到正确结果,但这是硬编码凑出来的巧合:只要ID长度不是9位,要么截不全ID,要么残留多余的引号字符,鲁棒性极差。
正确实现方式
不要硬编码固定偏移长度,先定位第二个双引号的位置,动态计算两个引号之间的内容长度即可,适配任意长度的ID:
#include <iostream> #include <fstream> #include <string> using namespace std; int main() { fstream file; string s; file.open("test.txt", ios::in); getline(file, s); size_t first_q = s.find('"'); size_t second_q = s.find('"', first_q + 1); string id = s.substr(first_q + 1, second_q - first_q - 1); cout << id << endl; file.close(); return 0; }
内容的提问来源于stack exchange,提问作者powerover9001
相关产品推荐
相关产品推荐

