首页 > 解决方案 > 将包含科学计数法数字的字符串矩阵转换为单行数组

问题描述

我在一个文本文件中有一个数字矩阵,如下所示:

0.0000e+00 100.00E-15 -100.00E-15
2.5000e-02 100.00E-15 -150.00E-15
5.0000e-02 150.00E-15 -100.00E-15
7.5000e-02 100.00E-15 -1000. -15
1.0000e-01 100.00E-15 -100.00E-15
1.2500e-01 100.00E-15 -100.00E-15
1.5000e-01 150.00E-15 -100.00E-15
1.7500e-01 150.00E-15 - 100.00E-15
2.0000e-01 150.00E-15 -100.00E-15
2.2500e-01 200.00E-15 -100.00E-15
2.5000e-01 150.00E-15 -100.00E-15
2.7500E-01 200. 15 -150.00E-15

等等。

我可以使用 fgets 扫描它们,从而有效地制作一串很长的数字。我面临的问题是矩阵的大小是可变长度的,而且我对编程比较陌生,所以我唯一知道如何处理这个问题的知识是使用 sscanf 和 atof。但是,当我尝试将 atof 转换的值存储到数组中时,它会出现奇怪的行为(例如“记住”最后一次 atof 转换,或者只是输入 0。)

char * strArr[numData][1000];
double varArr[numData];  /* number of data values in the matrix, in this case, 36 */
int i = 0;
int j = 0;

/* The actual data is preceded by a header, hence 8 */
/* dataArr is the lines of the text file that I retrieved using fgets */
/* I'm attempting to store each "string" in a string array, and then convert them to floats using the second loop */

for (i = 8; i < lineCount; i++)
{
    sscanf(dataArr[i], "%s %s %s", strArr[j], strArr[j+1], strArr[j+2]);
    j = j + 3;
}

for (i = 0; i < numData; i++);
{
    varArr[i] = atof(strArr[i]);
}

最后一部分给了我 varArr[i] 的错误值错误。老实说,我在这一点上有点油炸。

strArr[i] 是正确的浮点数作为字符串, atof(strArr[i]) 是正确的浮点数,但是当我尝试将 atof(strArr[i]) 存储到 varArr[i] (这是一个数组浮点数)我得到 0.000000e+000。我错过了什么?

例如

strArr[1] returns 100.00E-15
atof(strArr[1]) returns 100.00E-15
varArr[1] = atof(strArr[1]) returns 0.000000e+000

编辑 2:已解决

原来我需要将 atof 函数放在第一个循环中,例如:

for (i = 8; i < lineCount; i++)
    {
        sscanf(dataArr[i], "%s %s %s", strArr[j], strArr[j+1], strArr[j+2]);
        varArr[j] = atof(strArr[j]);
        varArr[j+1] = atof(strArr[j+1]);
        varArr[j+2] = atof(strArr[j+2]);
        j = j + 3;
    }

我不知道为什么,但它有效,所以我很高兴。

标签: c

解决方案


在 C 中正确使用字符串通常涉及动态分配以及仔细考虑何时以及何时分配和释放什么。这很难做对,你真的想让字符串尽可能少。

如果您不想处理异常长的输入行(似乎是您的情况),您可以只使用一个字符串缓冲区,该缓冲区仅临时保存字符串,直到以下字符串替换它:

char strArr[1000];

用来fgets填充它。然后使用sscanf从中获取数字:

sscanf(strArr, "%f %f %f", &varArr[j], &varArr[j+1], &varArr[j+2]);

注意:无需从一个字符串中提取 3 个字符串,并将每个字符串单独转换为float. 立即提取 3 个浮点数,就像上面的代码一样,消除了额外的字符串及其内存管理。


推荐阅读