xeex
xeex

Reputation: 209

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

I have a CSV file where the values are separated by commas, something like this:

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

All the values must be treated as floats.

The problem is when I try to read the values as floats:

fscanf(file,%f,&value);

If I print the result

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

I get:

The first value is 224,321

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

Upvotes: 2

Views: 4186

Answers (7)

chux
chux

Reputation: 153547

C solution

The OP's scanf() is evidently using floating point decimal_point of of ",". Unfortunately the data uses a decimal_point of of ".".

The C solution is 4 steps: 1) Determine the current locale 2) change locale 3) call sscanf() 4) restore locale.

#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();
}

Upvotes: 2

James Kanze
James Kanze

Reputation: 153929

Whether the comma is considered a decimal separator or not depends on the locale. You've labeled this for both C and C++; in this case, the solution is different.

In C++, forget about fscanf and use std::istream. Then imbue your stream with std::locale("C").

In C, it's a lot harder, since you have to change the global locale. And almost certainly restore it. And if you're multithreaded, do so in a critical section, protected from anyone else who might want to modify the locale as well.

Upvotes: 0

Paul92
Paul92

Reputation: 9062

Your post is a little bit ambiguous. You said that in your file you have values separated by comma, and after that you say that you want to read a float value that has comma instead of dot.

Anyway, the default behaviour is to take commas as separators, so 123,324 is readed like 123.00. But, in the following reading, you will get the same value. So, you may want to write it like this:

fscanf(file,"%f, ",&value);

If you want to use comma as a separator, instead of dot (altough I see that you have some values using dot), then you need another separator, like a space, in your files, to separe 2 consecutive values. The file you specified can not be used like this.

Upvotes: 0

huangxf
huangxf

Reputation: 1

CVS format contains a bunch of data divided by comma. So when you're trying to parse a cvs file, you have to put the comma symbol as part of your format parameter in scanf function. I believe the following code would be helpful.

#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;
}

Upvotes: 0

user2938830
user2938830

Reputation:

I'm slightly new to coding, but wouldn't you be able to simply remove the comma first and then read it? Simply use a function that runs through the line and eliminates all commas. This seems like the simplest solution to me.

Upvotes: 0

user2249683
user2249683

Reputation:

Simple answer: The format is ambiguous. Ether quote values or disambiguate by choosing a different separator (maybe a semicolon)

Another answer (if floating point values have no comma): Switch to the "C"-locale.

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409196

One way is to read it as integers, then convert to floating point.

Another is to read line-by-line, split at the comma, and convert each number one-by-one to floating point values.

Both of these solutions have very nice and pretty simple C++ implementations. More work to do it in C.

Upvotes: -1

Related Questions