harryw
harryw

Reputation: 33

ESP_IDF_ Add value of double pointer to struct c doesn't work_

I would like to pass the value of a double pointer to certain members of a struct. I ve function which returns a double pointer. Basically I can access and print the different values of the pointer. The external function parse_csv which delivers the double pointer is from this github repo [repo][1] But I can't parse it into my struct. If I m trying to print the value of the struct with printf. I doesn't print anything. The program just stops at this point.

struct.h. is where I ve defined my struct

#ifndef STRUCT_H
#define STRUCT_H
extern struct data* {
char* value1;
int value2;
int value3;
float value4;

}

#endif

readcsv.c

#include "struct.h"
struct data* data1;
char **parse_csv( const char *line ) {
    char **buf, **bptr, *tmp, *tptr;
    const char *ptr;
    int fieldcnt, fQuote, fEnd;

    fieldcnt = count_fields( line );

    if ( fieldcnt == -1 ) {
        return NULL;
    }

    buf = malloc( sizeof(char*) * (fieldcnt+1) );

    if ( !buf ) {
        return NULL;
    }

    tmp = malloc( strlen(line) + 1 );

    if ( !tmp ) {
        free( buf );
        return NULL;
    }

    bptr = buf;

    for ( ptr = line, fQuote = 0, *tmp = '\0', tptr = tmp, fEnd = 0; ; ptr++ ) {        if ( fQuote ) {
            if ( !*ptr ) {
                break;
            }

            if ( *ptr == '\"' ) {
                if ( ptr[1] == '\"' ) {
                    *tptr++ = '\"';
                    ptr++;
                    continue;
                }
                fQuote = 0;
            }
            else {
                *tptr++ = *ptr;
            }

            continue;
        }

        switch( *ptr ) {
            case '\"':
                fQuote = 1;
                continue;
            case '\0':
                fEnd = 1;
            case ',':
                *tptr = '\0';
                *bptr = strdup( tmp );

                if ( !*bptr ) {
                    for ( bptr--; bptr >= buf; bptr-- ) {
                        free( *bptr );
                    }
                    free( buf );
                    free( tmp );

                    return NULL;
                }

                bptr++;
                tptr = tmp;

                if ( fEnd ) {
                    break;
                } else {
                    continue;
                }
            default:
                *tptr++ = *ptr;
                continue;
        }

        if ( fEnd ) {
            break;
        }
    }

    *bptr = NULL;
    free( tmp );
    return buf;
}

char *fread_csv_line(FILE *fp, int max_line_size, int *done, int *err) {
    static FILE *bookmark;
    static char read_buf[READ_BLOCK_SIZE], *read_ptr, *read_end;
    static int fread_len, prev_max_line_size = -1;
    static char *buf;
    char *bptr, *limit;
    char ch;
    int fQuote;

    if ( max_line_size > prev_max_line_size ) {
        if ( prev_max_line_size != -1 ) {
            free( buf );
        }
        buf = malloc( max_line_size + 1 );
        if ( !buf ) {
            *err = CSV_ERR_NO_MEMORY;
            prev_max_line_size = -1;
            return NULL;
        }
        prev_max_line_size = max_line_size;
    }
    bptr = buf;
    limit = buf + max_line_size;

    if ( bookmark != fp ) {
        read_ptr = read_end = read_buf + READ_BLOCK_SIZE;
        bookmark = fp;
    }

    for ( fQuote = 0; ; ) {
        QUICK_GETC(ch, fp);

        if ( !ch || (ch == '\n' && !fQuote)) {
            break;
        }

        if ( bptr >= limit ) {
            free( buf );
            *err = CSV_ERR_LONGLINE;
            return NULL;
        }
        *bptr++ = ch;

        if ( fQuote ) {
            if ( ch == '\"' ) {
                QUICK_GETC(ch, fp);

                if ( ch != '\"' ) {
                    if ( !ch || ch == '\n' ) {
                        break;
                    }
                    fQuote = 0;
                }
                *bptr++ = ch;
            }
        } else if ( ch == '\"' ) {
            fQuote = 1;
        }
    }

    *done = !ch;
    *bptr = '\0';
    return strdup(buf);
}
static int count_fields( const char *line ) {
    const char *ptr;
    int cnt, fQuote;

    for ( cnt = 1, fQuote = 0, ptr = line; *ptr; ptr++ ) {
        if ( fQuote ) {
            if ( *ptr == '\"' ) {
                fQuote = 0;
            }
            continue;
        }

        switch( *ptr ) {
            case '\"':
                fQuote = 1;
                continue;
            case ',':
                cnt++;
                continue;
            default:
                continue;
        }
    }

    if ( fQuote ) {
        return -1;
    }

    return cnt;
}

void parse_data_to_struct(){
static char *buf1;
char **parsed_data;
FILE  *f = fopen("example.csv, "r");
    buf1 = fread_csv_line(f,max_amnt_char,&done,&err);
    parsed_data = parse_csv(buffer);
 printf("%s \n",parsed_data[2]);

 strcpy(data1[i].value1, parsed_data[1]);
 printf("%s \n",data1[i].value1);//this actually doesn t print anything
    data1[i].value2=atoi(parsed_data[0]);
}
#include readcsv.c

int app_main(void){
parse_data_to_struct();
return 0;
}
Here is an example csv

Index,User Id,First Name,Last Name,Sex,Email,Phone,Date of birth,Job Title 1,88F7B33d2bcf9f5,Shelby,Terrell,Male,[email protected],001-084-906-7849x73518,1945-10-26,Games developer,\n 2,f90cD3E76f1A9b9,Phillip,Summers,Female,[email protected],214.112.6044x4913,1910-03-24,Phytotherapist,\n 3,DbeAb8CcdfeFC2c,Kristine,Travis,Male,[email protected],277.609.7938,1992-07-02,Homeopath,\n



  [1]: https://github.com/semitrivial/csv_parser

Upvotes: 1

Views: 48

Answers (1)

OldBoy
OldBoy

Reputation: 807

Here is a much simpler csv parser that returns a null terminated array of tokens split from the line of text passed in.

char **parse_csv( const char *line )
{
    char* data = malloc(strlen(line) + 1);
    strcpy(data, line);

    char** fields;
    int field_count = 0;
    for (int i = 0; data[i] != '\0'; ++i)
    {
        if (data[i] == ',')
            field_count += 1;
    }
    fields = malloc(sizeof(char*) * (field_count + 1));

    char* token;
    char* context;
    token = strtok_s(data, ",\n", &context);
    int field_index = 0;
    while (token != NULL)
    {
        fields[field_index] = (char*)malloc(strlen(token) + 1);
        strcpy(fields[field_index], token);
        field_index++;
        fields[field_index] = NULL;
        token = strtok_s(NULL, ",\n", &context);
    }
    return fields;
}

You can test it with the following code:

int main()
{
    char** stuff = parse_csv("1,88F7B33d2bcf9f5,Shelby,Terrell,Male,[email protected],001-084-906-7849x73518,1945-10-26,Games developer,\n");
    while (*stuff != NULL)
    {
        printf("Item: %s\n", *stuff);
        stuff++;
    }
}

So in your real application you need to pass each line from the csv file and process the returned tokens as appropriate. I have deliberately not handled double quotes as they do not appear in your sample data, but additional code to process them can be added later.

Upvotes: 0

Related Questions