当浮点值有逗号而不是点时,如何读取该值

How do i read a float value when this value have comma instead of dot?

本文关键字:何读取 读取      更新时间:2023-10-16

我有一个CSV文件,其中的值用逗号分隔,如下所示:

224,321,345,56.6
225,322,245,46.7
etc,etc,etc.....

所有值都必须被视为浮点数。

问题是当我尝试将值读取为浮点数时:

fscanf(file,%f,&value);

如果我打印结果

printf("The first value is: %f",value) 

我得到:

The first value is 224,321

当浮点值有逗号而不是点时,如何读取该值?

C 解决方案

OP 的scanf()显然使用了 "," 的浮点decimal_point。 不幸的是,数据使用了 "."decimal_point

C 解决方案分为 4 个步骤:1) 确定当前区域设置,2) 更改区域设置,3) 调用sscanf() 4) 恢复区域设置。

#include <locale.h>
// Maybe CurrentLocaleName = "" will work.
// That's the locale-specific native environment.
// Otherwise the value may be available in preceding code.
const char *CurrentLocaleName = TBD();  
// In the "C" locale, a decimal_point is ".".
if (NULL == setlocale(LC_NUMERIC, "C")) {
  handle_local_change_error();
}
if (first_in_line) {
  if (1 != fscanf(file, "%f", &value)) {
    handle_scan_error();
  }
}
else {
  if (1 != fscanf(file, " ,%f", &value)) {
    handle_scan_error();
  }
}
if (NULL == setlocale(LC_NUMERIC, CurrentLocaleName)) {
  handle_local_change_error();
}

简单的答案:格式不明确。以太引用值或通过选择不同的分隔符(可能是分号)来消除歧义

另一个答案(如果浮点值没有逗号):切换到"C"区域设置。

我对编码有点陌生,但你不能简单地先删除逗号然后再阅读它吗?只需使用贯穿全行并消除所有逗号的函数即可。这对我来说似乎是最简单的解决方案。

CVS 格式包含一堆用逗号分隔的数据。因此,当您尝试解析 cvs 文件时,您必须将逗号符号作为 scanf 函数中格式参数的一部分。我相信以下代码会有所帮助。

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
int main(int argc, char * argv[]) {
    if(argc <= 1) {
        printf("No file specified!n");
        exit(0);
    }
    char * filename = argv[1];
    FILE *file = fopen(filename,"rb");
    if(0 != file) {
        float value = 0;
        while(!feof(file)) {
            fscanf(file, "%f,", &value);
            printf("%f ",value);
        }
        printf("n");
    }
    fclose(file);
    return 0;
}

你的帖子有点模棱两可。您说在您的文件中您有用逗号分隔的值,然后您说您要读取带有逗号而不是点的浮点值。

无论如何,默认行为是将逗号作为分隔符,因此 123,324 的读取方式类似于 123.00。但是,在下面的阅读中,您将获得相同的值。所以,你可能想这样写:

fscanf(file,"%f, ",&value);
如果您想使用逗号而不是点作为分隔符

(尽管我看到您有一些使用点的值),那么您需要在文件中使用另一个分隔符(例如空格)来分隔 2 个连续值。您指定的文件不能这样使用。

号是否被视为小数分隔符取决于区域设置。 您已经为 C 和 C++ 标记了此内容;在这种情况下,解决方案是不同的。

在C++,忘记fscanf并使用std::istream. 然后让您的溪流充满std::locale("C") .

在 C 中,这要困难得多,因为您必须更改全局现场。 几乎可以肯定的是恢复它。 如果你是多线程,在关键部分执行此操作,免受保护其他可能想要修改区域设置的人。

一种方法是将其读取为整数,然后转换为浮点数。

另一种是逐行读取,在逗号处拆分,并将每个数字逐个转换为浮点值。

这两种解决方案都有非常好且非常简单的C++实现。在 C 语言中还有更多工作要做。