C++:如何从char*字符串中按位置解析指定数值?
解决C风格字符串解析提取数值的问题
咱们先理清你遇到的问题根源:
- 用
row.substr()报错,是因为row是char*类型(C风格字符串),而substr是C++标准库std::string的专属成员函数,两者不能直接混用; memcpy提取出现冗余数据,大概率是因为你没有给提取后的子串添加字符串结束符'\0',或者计算的截取长度有误,导致内存中相邻的其他数据被当成了当前字符串的一部分。
下面给你两种可靠的解决方案,完美适配你的场景:
方法一:转换为std::string处理(C++风格)
把char*转成std::string后,就能方便地使用字符串查找、截取方法了,步骤如下:
- 将
char*类型的row转换为std::string; - 用
find()方法定位逗号的位置,分割出A和P之前的数值子串; - 用
stod()(string to double)将子串转换为double类型。
示例代码:
#include <string> #include <iostream> int main() { char* row = (char*)"GR123,7894.5444,A,4687.5643,P"; std::string str_row(row); // 提取A之前的数值:找到第一个逗号和第二个逗号的位置 size_t first_comma = str_row.find(','); size_t second_comma = str_row.find(',', first_comma + 1); std::string valA_str = str_row.substr(first_comma + 1, second_comma - first_comma - 1); double valA = std::stod(valA_str); // 提取P之前的数值:找到第三个逗号和第四个逗号的位置 size_t third_comma = str_row.find(',', second_comma + 1); size_t fourth_comma = str_row.find(',', third_comma + 1); std::string valP_str = str_row.substr(third_comma + 1, fourth_comma - third_comma - 1); double valP = std::stod(valP_str); std::cout << "A之前的数值:" << valA << std::endl; std::cout << "P之前的数值:" << valP << std::endl; return 0; }
方法二:用sscanf直接匹配格式(C风格,更简洁)
因为你的每行数据格式是固定的(GRxxx,数值,A,数值,P),用C标准库的sscanf可以直接按格式提取数值,不需要手动处理字符串分割,非常高效:
示例代码:
#include <cstdio> #include <iostream> int main() { char* row = (char*)"GR123,7894.5444,A,4687.5643,P"; double valA, valP; // %*[^,] 表示跳过第一个逗号前的所有字符(*表示不存储) // %lf 读取double类型数值,后面的,A,和,P是固定的分隔符,直接匹配 int result = sscanf(row, "%*[^,],%lf,A,%lf,P", &valA, &valP); if (result == 2) { // 成功读取2个数值 std::cout << "A之前的数值:" << valA << std::endl; std::cout << "P之前的数值:" << valP << std::endl; } else { std::cout << "解析失败" << std::endl; } return 0; }
这个方法的好处是不需要手动计算字符位置,只要格式固定,就能精准提取,还能通过返回值判断是否解析成功。
内容的提问来源于stack exchange,提问作者shizde
相关产品推荐
相关产品推荐

