【问题标题】:C++ - How to parse a char* substring into int? [duplicate]C++ - 如何将 char* 子字符串解析为 int? [复制]
【发布时间】:2020-10-19 14:41:45
【问题描述】:

我正在处理一个模拟文件。该文件有许多行,包含数字、字母和字符。

例子:

    GR123,7894.5444,A,4687.5643,P
    GR456,1234.6556,A,9657.5686,P
    GR789,2344.3422,A,9786.8465,P
    GR987,6522.6354,A,3245.5754,P

我需要取 A 和 P 之前的值(对于第一行,7894.5444 和 4687.5643)。

如何通过将此字符串定位到 int 进行解析?已经尝试过:

    double exampleA = stoi(row.substr(6,9));
    double exampleP = stoi(row.substr(18,9));

但它给了我这个错误:request for member ‘substr’ in ‘row’, which is of non-class type ‘char*’

也试过了:

    char exampleA[9];
    char exampleP[9];

    memcpy(&exampleA, &row[6],sizeof(exampleA));
    memcpy(&exampleP, &row[6],sizeof(exampleP));

为了在将值从行中分离出来后进行转换,但 memcpy 缓冲区总是将 exampleP 的值与 exampleA 一起带来:

    A : 7894.5444
    P : 4687.5643?7894.5444

【问题讨论】:

  • 您正在尝试对char* 使用std::string 语法,为什么不首先使用std::string
  • 它不是 CSV 文件,而是 TXT 文件。我会尝试调整这个问题的答案

标签: c++ string parsing


【解决方案1】:

request for member ‘substr’ in ‘row’, which is of non-class type ‘char*’

是的,你不能在指针上调用substr。也许您打算将这些内容存储在 std::string 实例中?

关于你的第二次尝试,你写的东西有很多大问题:

  1. 您使用的缓冲区长 9 个字节,但您示例中的最大数字看起来是 10 个字节 (4 + 1 + 4 + 1)。您正在溢出缓冲区并覆盖进程中的随机内存。编辑:或者,如果您编写了正确的以空字符结尾的字符串,您就会这样做。

  2. 与上面有关,因为它有点隐藏问题,所以不要使用memcpy 来复制字符串。更好的第一次尝试是 strncpy 将子字符串复制到缓冲区,但您仍然必须手动将其终止。

P 行显示这两个条目的原因是您的编译器似乎将exampleA 放在堆栈上exampleP 之后,由保护字符分隔,并且由于您没有以空值终止您的字符串,试图显示exampleP 溢出到exampleA,这完全是幸运的,后面似乎是一个空字符。

【讨论】:

  • 我在使用 strncpy 时遇到了同样的问题。能不能帮我看看要使用的代码吗?
  • 您是否对字符串进行了空终止?
  • 不,因为我收到的那些 txt 文件已经采用了那种格式。我应该在迭代中添加一个 '\0' 吗?
  • “不,因为我已经收到了那些格式的 txt 文件”——这与你的文件无关,在 C 中所有字符串都必须以空值结尾。
【解决方案2】:

由于数据似乎无论如何都在 C 字符串中,您不妨使用std::strtod,它的优点是不需要您复制子字符串:

char* endp;
double exampleA = std::strtod(row+6, &endp);
double exampleP = std::strtod(row+18, &endp);

在这两种情况下,您可能都需要仔细检查 *endp == ',' 是否未发出转换错误信号。

当然,即使是std::string,您也可以使用std::strtod。这通常是最有效的解决方案。

请注意,strtod 是区域设置感知的,因此如果输入与您当前的区域设置不对应(例如,文件使用句点 fir 小数和逗号作为字段分隔符,而区域设置使用逗号和分号,则这可能不起作用,分别)。

我不确定您将浮点数转换为整数是什么意思(截断?舍入?乘以 10,000?)。所以我没有解决这部分问题。

【讨论】:

  • 返回错误error: cannot resolve overloaded function ‘end’ based on conversion to type ‘char**’
  • 您执行using namespace std; 并遇到问题。 Why is "using namespace std;" considered bad practice?
  • 我将 end 更改为 endp 以防万一。但我同意using namespace std; 带来的问题多于其价值。
猜你喜欢
  • 1970-01-01
  • 2016-07-17
  • 2010-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-25
  • 2020-07-08
  • 2013-08-16
相关资源
最近更新 更多