0

I'm writing a C++ program which reads a .txt-file of floats and converts it into an array. The .txt-file has a structure like this:

115;-83.570045;-1.082268;26.332237;0.019520;-0.976976;0.123464;2.601000;-1.224000;-0.306000;329.895233;-824.890686;28.381367;27.530001;963.750000
119;-82.757698;-1.187364;26.512978;0.026840;-0.975024;0.124928;1.530000;-3.060000;0.612000;317.688202;-812.683655;26.855488;27.530001;963.780029
121;-83.921730;-2.208382;27.361389;-0.002928;-1.015528;0.103456;4.284000;-20.348999;-7.650000;338.745361;-812.683655;16.479504;27.540001;963.760010
123;-83.580917;-4.218470;29.861431;0.145912;-1.009184;0.108824;0.918000;-0.153000;4.437000;341.797119;-803.833557;4.272464;27.530001;963.789978
...

The file has 2117 lines and every line consists of 15 numbers which are delimited by ";". Now my program so far:

std::ifstream input_file;
input_file.open("data.txt");
float sensor_data[2117][15];
std::string line;
std::string delimiter = ";";
int count = 0;

while (count < 2117 && input_file >> line) {
    size_t pos = 0;
    std::string token;
    int _count = 0;
    while ((pos = line.find(delimiter)) != std::string::npos) {
        token = line.substr(0, pos);
        sensor_data[count][_count] = std::stof(token);
        std::cout << "Read token: " << token << std::endl;
        line.erase(0, pos + delimiter.length());
    }
    
    count += 1;
    std::cout << "New line!" << std::endl << "---------" << std::endl;
}
std::cout << "Sample line: " << std::endl;
for (int i = 0; i < 15; i++) {
    std::cout << sensor_data[0][i] << " ";
}
input_file.close();

I'm basically combining the methods from here and here to first read line-by-line and then split the line according to the delimiter. Now the issue is while the cout-command in the middle produces good results like this, when I print out an example line at the end, the values in the array itself are completely nonsense.

// Output #1:
Read token: 5555
Read token: -85.951965
Read token: 51.452652
Read token: 3.685740
Read token: -0.607560
Read token: -0.671488
Read token: -0.019032
Read token: 6.426000
Read token: 9.486000
Read token: -20.042999
Read token: -180.664185
Read token: -210.266251
Read token: 43.334991
Read token: 30.940001
// Output #2:
Sample line: 
27.53 0 0 0 0 0 0 0 0 0 0 0 0 0 0

I tried to convert the values with this method instead, but that gave me the exact same output.

What am I doing wrong? Is there a reliable way to convert strings to float?

Totemi1324
  • 408
  • 2
  • 13
  • 1
    I really recommend using [`std::getline`](https://en.cppreference.com/w/cpp/string/basic_string/getline). Both for reading the lines from the file, *and* for parsing the input itself (you can use any arbitrary character as the "newline"). – Some programmer dude Sep 27 '20 at 19:59
  • 1
    _"Is there a reliable way to convert strings to float?"_ Sure there is: [`std::strtof()`](https://en.cppreference.com/w/cpp/string/byte/strtof). And as I had the same idea as @Some you need `getline()` used with `std::stringstream ss(line);` – πάντα ῥεῖ Sep 27 '20 at 19:59
  • the question [here](https://stackoverflow.com/questions/14265581/parse-split-a-string-in-c-using-string-delimiter-standard-c) is about a delimiter that is not a single character, the code in the question is fine for a single char delimiter. Using `getline` is much simpler than the answer you applied – 463035818_is_not_a_number Sep 27 '20 at 20:15
  • Alright, thanks for the advice! – Totemi1324 Sep 27 '20 at 21:43

1 Answers1

1

Your problem is that you never increment _count.

By the way, do not use names that start with _.

Eugene
  • 4,579
  • 1
  • 16
  • 29
  • 1
    I recently learned that using a single `_` prefix is perfectly standard conformant, while `__` isn't. – πάντα ῥεῖ Sep 27 '20 at 20:09
  • 1
    @πάνταῥεῖ `_` prefix is prohibited by the standard if followed by uppercase. I did not say `_count` is prohibited, but gave advice about good style. – Eugene Sep 27 '20 at 20:13
  • 1
    ..if followed by uppercase. If not I don't see why it would be good to avoid such names – 463035818_is_not_a_number Sep 27 '20 at 20:19
  • @Eugene Thanks for pointing out, this was really the issue. I feel sort of dumb now But I don't really get what you have against the variable name. As for the other programming languages I work with, I learned that variables with _ at the beginning are commonly used in functions or algorithms where they represent temporarily used variables which are not worth properly naming. By putting an _ at the beginning, you avoid that such variables take away availible names for the important ones. – Totemi1324 Sep 27 '20 at 21:47
  • 1
    `_` is frowned upon in `C++` community. The standard prohibits using `_` followed by uppercase letter (because it reserves such symbols for standard library implementation). `_` followed by a lowercase is formally ok, but many non-standard C++ library functions start with it, and there may be a confusion. – Eugene Sep 27 '20 at 21:56
  • On the other hand, *ending* variables with `_` is accepted by everybody. – Eugene Sep 27 '20 at 22:09