使用C/C++有效地反序列化由浮点数,标记和空行组成的字符串

Mon*_*urd 4 c c++ string floating-point parsing

我有大字符串,类似于以下...

some_text_token

24.325973 -20.638823  

-1.964366 0.753947  
-1.290811 -3.547422  
0.813014 -3.547227  

0.472015 3.723311  
-0.719116 3.676793  

other_text_token  

24.325973 20.638823  

-1.964366 0.753947  
-1.290811 -3.547422  
-1.996611 -2.877422  
0.813014 -3.547227  

1.632365 2.083673  
0.472015 3.723311  
-0.719116 3.676793  

...

...我正在尝试有效地,并且在交错的序列中,它们出现在字符串中,抓住......

  1. 文本标记
  2. 浮动值
  3. 空白行

......但我遇到了麻烦.

我已经尝试过strtod并成功地从字符串中抓取了浮点数,但我似乎无法使用strtod获取循环来向我报告交错的文本标记和空行.我不是100%自信strtod是"正确的轨道"给出交错的令牌和空白行,我也感兴趣.

字符串中存在标记和空行以给浮点数提供上下文,因此我的程序知道每个标记之后要使用的浮点值是什么,但是strtod看起来更加适应,可以理解,只是报告它遇到的浮点数一个字符串,不考虑空白行或令牌等愚蠢的东西.

我知道这在概念上并不是很难,但是对C/C++来说相对较新我在判断我应该关注哪些语言特性以最大限度地利用C/C++能够对这个问题产生的效率时遇到困难.

有什么指针吗?我非常感兴趣为什么各种方法的功能或多或少都有效.谢谢!!!

Alo*_*hal 5

使用C,我会做这样的事情(未经测试):

#include <stdio.h>

#define MAX 128

char buf[MAX];
while (fgets(buf, sizeof buf, fp) != NULL) {
    double d1, d2;
    if (buf[0] == '\n') {
        /* saw blank line */
    } else if (sscanf(buf, "%lf%lf", &d1, &d2) != 2) {
        /* buf has the next text token, including '\n' */
    } else {
        /* use the two doubles, d1, and d2 */
    }
}
Run Code Online (Sandbox Code Playgroud)

首先检查空行是因为它相对便宜.根据您的需要:

  1. 你可能需要增加/改变MAX,
  2. 您可能需要检查是否buf以换行结束,如果没有,则行太长(在这种情况下转到1或3),
  3. 你可能需要一个从文件中读取完整行的函数,使用malloc()realloc()动态分配缓冲区(有关更多信息,请参阅内容),
  4. 你可能想要处理特殊情况,例如一行上的单个浮点值(我假设不会发生这种情况). sscanf()返回成功匹配和分配的输入项的数量.

我也假设空行是空白的(只是换行符本身).如果没有,您将需要跳过前导空格. isspace()in ctype.h在这种情况下很有用.

fpFILE *由返回的有效对象fopen().