0

I need help in converting data as simple and memory not-intensive as possible. So the data is in a string that looks like this:

4519.8081,01426.5819
4519.8081,01426.5818
4519.8082,01426.5815
4519.8083,01426.5812

I need to convert this from the string so I get two float arrays y and x. Array y should contain the values from the first column (columns are delimited with comma) Array x should contain the values from the second column.

This will be done on a microcontroller so I really need it as minimalistic as possible!

Update: I thought this was enough information just to get a function or pointers on how to do the function, my apologies.

The general objective is to log GPS data in order to get several coordinate points from which I can draw a traveled path. It will be roughly visualized on a 320x240 TFT screen. I use an ATmega32 MCU together with a GPS module, SD card reader and the mentioned screen of course.

To elaborate - I am logging GPS data in the mentioned format. The data gets written down to a txt file

4519.8081,01426.5819
4519.8081,01426.5818
4519.8082,01426.5815
4519.8083,01426.5812

Every line is one logged point with it's latitude and longitude. 4519.8081, 01426.5819 is actually 45°19.8081'. 14°26.5819'

After logging a certain number of points (haven't defined the exact number yet but it will be a limited number due to the memory constraints) to the SD card I have the data stored.

At this point I need to convert the data I have into two arrays which will serve as coordinates for plotting these points on the display and plotting a path between them.

So if I have an array X[n] and array Y[n] with the coordinates, I do something like this:

for (int i=0; i<n-1; i++){
    display.drawLine(x[i], y[i], x[i+1], y[i+1])
}

This will loop through the arrays and plot the path from the coordinates.

Now, I understand that the coordinates have to be in the 320x240 range since that is the resolution of my display. That is why I can't just pass the float numbers as they are (if I can even get them!!) but I need to do some calculations on the arrays first.

But all in all, for starters, I just need to get the values from the string into float arrays, e.g.

x[] = {4519.8081, 4519.8081, 4519.8082, 4519.8083}
y[] = {1426.5819, 1426.5818, 1426.5815, 1426.5812}

If there is a better way to accomplish what I need, feel free to comment.

I hope that is enough information for my question to get unblocked. Thanks in advance!

6
  • 1
    🐴 This is an “I want a pony” type of question that’s difficult to answer concisely and is off-topic on Stack Overflow. If you can, make an attempt and then show us your code we can understand what you’re trying to do on a technical level. Even a small amount of code, however incomplete or broken, can give us context and illustrate your intentions. Instead of leaving us to speculate on what you might need, give us something to build so we can focus help in those areas where it’s most needed. Commented May 11, 2020 at 22:23
  • 1
    Time to refresh the help pages, especially "What topics can I ask about here?" and "What types of questions should I avoid asking?". Also take the tour and read How to Ask and this question checklist. Lastly don't forget how to create a minimal reproducible example of your own attempt, and edit your question to include it together with a detailed description of the problems with your attempt. Commented May 11, 2020 at 22:27
  • 4
    Aside: please note that float does not have enough significance to distinguish 4519.8081 from 4519.8082. And generally, floating point is not minimalist. Commented May 11, 2020 at 22:46
  • 1
    When and where and how often will you parse data like this? How much data will you parse each time? How "minimalistic" is your microprocessor (make, model, etc.)? How much of the standard C functions can you reliably use? Do your microprocessor have floating-point support, or is it handled by the library or the compiler, or not at all? Commented May 11, 2020 at 23:26
  • Machi, If familiar with fgets()., start by reading lines of input with that. Commented May 13, 2020 at 2:16

2 Answers 2

1

I would do something like this:

char *input_string = "..."; // Assume properly null terminated.
float y[N]; // Assume some maximum capacity or if N known.
float x[N]; // Probably allocated using malloc here if N large
float num;
int ind = 0;
while (1) {
    // Assume the string does not start with a new line.
    int n_read = sscanf(input_string, "%f%f", &y[ind], &x[ind]);
    if (n_read != 2) {
        // EOF or bad read
        break;
    }

    ind++;

    if (ind >= N) {
       // Too many floats to fit in array.
       break;
    }

    // Move past the next newline.
    input_string = strchr(input_string, '\n');
    if (input_string == NULL) {
        break;
    }

    input_string++;
}

It's untested and not super clean but should be enough to get you started. Also keep in mind as Weather Vane points out, floats cannot represent all values exactly. Perhaps you can consider fixed point depending on your use case.

If you don't know the number of rows in the string and don't want to have a maximum array length, you can prescan the string and later malloc an array of the exact size you need.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks so much, I used this with some altering and it works good. That is, it works good on my computer. There is a known problem with sscanf and avr-gcc which compiles it for the MCU. sscanf and float do not work together very well so it wasn't working on the MCU. Lost about 6 hours of work trying to figure it out only to discover it wasn't a problem with my code at all. But there is a fix, will apply it tomorrrow. Thanks a bunch again!!!
1

First create the data file by

cat > data.txt <<EOF1
> 4519.8081,01426.5819
> 4519.8081,01426.5818
> 4519.8082,01426.5815
> 4519.8083,01426.5812
> EOF1

Then create the following C file

#include <stdio.h>
#define NUM_ITEMS 10

int main() {

    float y[NUM_ITEMS], x[NUM_ITEMS];
    int i = 0;

    while (scanf("%f,%f\n", &y[i], &x[i]) > 0) i++;

    while (i>0) {
        i--;
        printf("%f %f\n", y[i], x[i]);
    }

    return 0;
}

After compiling it, execute

./a.out < data.txt

The program creates and prints the float arrays (corresponding to y and x coordinates) in reverse order.

1 Comment

Why > 0 versus == 2?. A return value of 1 implies nothing read into &x[i].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.