0

I have following struct

typedef struct
{
    char* city;
    int temp;
} Place;`

I am attempting to read in two values from a line into an array of structs.

The lines look like:

Los Angeles; 88

I am attempting to read data into the array. Assuming my memory allocation is correct what is the correct way to read in these values.

my code

    void readData(FILE** fpData, FILE** fpOutput)
{
    char s[100];
    int index = 0;

    Place *values;
    values=malloc(size * sizeof(Place));
    if (values == NULL)
    {
        MEM_ERROR;
        exit(1);
    }


    for (int a = 0; a < size; a++)
    {
        (values[a]).city = (char *) malloc(100 * sizeof(char));
        if(values[a].city == NULL)
        {
            MEM_ERROR;
            exit(100);
        }
    }

    while(fgets(s, sizeof(s), *fpData)!=NULL)
    {
        sscanf(s, "%[^:]%*c%d\n", values[index].city, &values[index].temp);
        index++;
    }

    sortInsertion(values, size, fpOutput);

    free(values);
    return;
}

The city is not going into the array so I am assuming the part where it says values[index].city is incorrect.

How can I fix this ?

5
  • @hii There is a need to ensure the area for city. also "%[^:]%*c%d\n" : : typo --> ; Commented Apr 18, 2015 at 2:09
  • remove sscanf, use strtok on ';' to split the string and easily refer to the two datafields. and apply some validation as @BLUEPIXY suggests Commented Apr 18, 2015 at 2:09
  • Place *values; only define a pointer. You need to change this to array like Place values[100], or use malloc. Commented Apr 18, 2015 at 2:12
  • Also similar with char* city; inside the struct. Change this to char city[100]; Commented Apr 18, 2015 at 2:16
  • @hii Just want to make sure that you aware with this. Commented Apr 18, 2015 at 2:22

2 Answers 2

4

Your data using semicolon ; while your sscanf format using colon :, make sure this is same character. If your data really use semicolon, change %[^:] part in the sscanf format to %[^;]

Here my code and how I run it to show you that it works:

#include <stdio.h>

struct Place {
    char city[100];
    int  temp;
} values[30];

int main() {
    char s[100];
    int i=0, n=0;
    while ( fgets(s, sizeof(s), stdin) != NULL ) {
        sscanf(s, "%[^;]%*c%d\n", values[n].city, &values[n].temp);
        n++;
    }
    printf("n=%d\n", n);

    for ( i=0; i<n; i++ ) {
        printf("values[%d] = (%s, %d)\n", i, values[i].city, values[i].temp);
    }
}

This is how I run it on Linux:

% for a in `seq 1 3`; do echo "City-$a; $a$a"; done | ./a.out 
n=3
values[0] = (City-1, 11)
values[1] = (City-2, 22)
values[2] = (City-3, 33)
Sign up to request clarification or add additional context in comments.

Comments

2
sscanf(s, "%[^:]%*c%d\n", values[index].city, &values[index].temp);

This will copy everything from the start of the line read up to the first colon (:) into the city array you allocated. Your example input would seem to have a semi-colon (;), so you'll get the entire line in the city array and nothing in the temp field.

You don't do any input checking, so any too-long input line will get split into multiple (probably corrupted) cities. You'll also have problems if there are not exactly size lines in the file, as you don't check to make sure index doesn't go past size while reading, and you assume you have size entries at the end without checking.

Comments

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.