4

I can normally extract the data of array as:

#include <stdio.h>
int main()
{
    char str[100] = "The quick brown fox jumps over the lazy dog";
    char *c = (str + 29);
    printf("%s\n", c);
    return 0;
}

But if I have to extract data from the entire unsorted and n-sized array where n value may be more than 70 as like:

unsigned char buffer[n] = "00,00,00,11,30,45.00,a,1.1,b,d,16,ABC,98.0";
unsigned char buffer1[n] = "A,3,22,18,21,06,03,09,24,15,,,,,2.5,1.6,1.9*3E";

How can I extract some specific data like 45.00 from this unsorted array?

buzzed
  • 55
  • 8
  • 1
    If you know that `45.00` is in the data, why do you need to extract it? If you mean "how can I find out if `45.00` is in the data", then maybe `strstr()` is what you're after. Do you have to worry about a comma before the string (to avoid picking up `"12.00,145.00,29.00"` or the comma after it (to avoid picking up `"12.00,45.00"`)? What exactly are you trying to do? – Jonathan Leffler Jan 07 '22 at 04:40
  • The data inside the buffer is unknown, it is just an example of how the data are formatted. Yeah, all the data are separated by a comma. I want to extract some data from it. – buzzed Jan 07 '22 at 04:45
  • Use `strchr()` to find `','` from `buffer[]`. – chux - Reinstate Monica Jan 07 '22 at 04:46
  • OK — so you need to find a string such as `45.00` surrounded by commas, or at the start of the string followed by a comma, at the end of the string preceded by a comma? This avoids picking up `145.00`, or `45.001`. And you won't be trying to find strings that start or end with comments? And you won't be wanting to find `45` even though `45.00` and `45` are the same mathematically (even though they're different strings). – Jonathan Leffler Jan 07 '22 at 04:48
  • yeah, I need to find a string such as 45.00 surrounded by commas, or at the start of the string followed by a comma, at the end of the string preceded by a comma or like the example I showed in ```buffer1``` where there may not be data inside comma or not. – buzzed Jan 07 '22 at 04:55

1 Answers1

3

The split() method used in this suggestion was developed by @hmjd to answer the referenced post; I have made arragments on the split() method that will not change the result. The solution is accomplished in five steps marked in the source code:

  1. Using the split() method, the character array is split into tokens according to the ',' character.
  2. The total number of tokens is calculated to find the number of data in the field indicated by the **tokens pointer.
  3. Tokens are printed for testing purposes.
  4. The getIndex() method searches for a special character array among the tokens and returns the index if found.
  5. The returned index and data are printed.
#include <stdio.h>
#include <string.h> 
#include <stdlib.h>

/* (1) Splits a string by separator character. */
char** split(char* a_str, const char a_delim);
/* (2) Returns the total number of parts. */
size_t getSize(char **tokens);
/* (3) Prints tokens. */
void print(char **tokens);
/* (4) Searches for a data in tokens and returns the index of the result. */
int getIndex(char **tokens, char *search, size_t size);

int main()
{
    unsigned char buffer[] = "00,00,00,11,30,45.00,a,1.1,b,d,16,ABC,98.0";
    char search[] = "45.00";
    char **tokens = split(buffer, ',');                             /* 1 */
    size_t size =  getSize(tokens);                                 /* 2 */
    print(tokens);                                                  /* 3 */
    size_t index = getIndex(tokens, search, size);                  /* 4 */
    
    if(index >= 0)
        printf("Index: %ld Result: %s", index, *(tokens + index));  /* 5 */
    return 0;
}

char** split(char* a_str, const char a_delim)
{
    char** result = 0;
    size_t count = 0;
    char* tmp = a_str;
    char* last_comma = 0;
    char delim[2];
    delim[0] = a_delim;
    delim[1] = 0;

    while (*tmp)
    {
        if (a_delim == *tmp)
        {
            count++;
            last_comma = tmp;
        }
        tmp++;
    }
    count += last_comma < (a_str + strlen(a_str) - 1);
    count++;
    result = malloc(sizeof(char*) * count);

    if (result)
    {
        size_t idx  = 0;
        char* token = strtok(a_str, delim);

        while (token)
        {
            *(result + idx++) = strdup(token);
            token = strtok(0, delim);
        }
        *(result + idx) = 0;
    }
    return result;
}

int getIndex(char **tokens, char *search, size_t size)
{
    int index;
    if(tokens)
        for(index = 0 ; *(tokens + index) ; index++)
            if(strcmp(search, *(tokens + index)) == 0)
                return index;
    return -1;
}

void print(char **tokens)
{
    if (tokens)
        for (size_t index = 0; *(tokens + index); index++)
            printf("[%ld]: %s\t", index, *(tokens + index));
    printf("\n");
}

size_t getSize(char **tokens)
{
    size_t counter = 0;
    while(*(tokens + counter))
        ++counter;
    return counter;
}

This source code produces the following output:

[0]: 00 [1]: 00 [2]: 00 [3]: 11 [4]: 30 [5]: 45.00 [6]: a [7]: 1.1 [8]: b [9]: d [10]: 16 [11]: ABC [12]: 98.0
Index: 5 Result: 45.00

References
Sercan
  • 4,739
  • 3
  • 17
  • 36