简体   繁体   中英

set member of pointer to ponter of a Structure in a function

This is my new question since I'm so newbie!!! :)

I have a text file like:

3
55.33  44.27 STN1
77.26  33.44 STN2
22.11 23.12 STN5

I would like to read it in c.

so I have defined a structure in a file header entitle read_stn.h for the file like:

#include <stdio.h>
#include <sys/file.h>

typedef struct station
 {
     double lat, lon;
     char name[5];
 } station;

and try to read the file using following codes

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "read_stn.h"
void read_stn(char filename[], station **sta,int *station_no)
{
    FILE *fp;
    int i;
    char sta_str[5];
    float longitude, latitude;


    fp = fopen(filename,"r");
    fscanf(fp,"%d",station_no);
    printf("%d\n", *station_no);

    *sta = (station*)malloc(*station_no*sizeof(station *));

    for(i=0;i<*station_no;i++)
    {
        fscanf(fp,"%f %f %s", &longitude, &latitude, sta_str);
        printf("%f %f %s\n", longitude, latitude, sta_str);

        sta[i]->lon=(double)longitude;
        sta[i]->lat=(double)latitude;
        strcpy(sta[i]->name,sta_str);
    }

    fclose(fp);
}

and a main routine:

#include <stdio.h>
#include <stdlib.h>
#include "read_stn.h"

int main()
{
station *sta;
int i,stn_no;

read_stn("station.dat",&sta,&stn_no);

for(i=0;i<stn_no;i++)
{
    printf("%d %s %f %f\n",i+1, sta[i].name, sta[i].lon, sta[i].lat);
}

free(sta);
return 1;
}

but when I tried to read file I got segmentation core dump. Is there any error in my files. I think there is something error in defining the pointer to pointer member assigning. Would you help me?

You weren't far off, a couple errors.

This:

*sta = (station*)malloc(*station_no*sizeof(station *));

should be this:

*sta = malloc(*station_no * sizeof(station));

since you want to allocate memory for several structs, not for several struct pointers.

Then this:

sta[i]->lon=(double)longitude;
sta[i]->lat=(double)latitude;
strcpy(sta[i]->name,sta_str);

should be:

(*sta)[i].lon = (double) longitude;
(*sta)[i].lat = (double) latitude;
strcpy((*sta)[i].name, sta_str);

since your dynamic array is stored at *sta , not at sta .

Full working version:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct station {
    double lat, lon;
    char name[5];
} station;

void read_stn(char filename[], station ** sta, int *station_no) {
    FILE *fp;
    int i;
    char sta_str[5];
    float longitude, latitude;

    fp = fopen(filename, "r");
    fscanf(fp, "%d", station_no);
    printf("%d\n", *station_no);

    *sta = malloc(*station_no * sizeof(station));

    for (i = 0; i < *station_no; i++) {
        fscanf(fp, "%f %f %s", &longitude, &latitude, sta_str);
        printf("%f %f %s\n", longitude, latitude, sta_str);

        (*sta)[i].lon = (double) longitude;
        (*sta)[i].lat = (double) latitude;
        strcpy((*sta)[i].name, sta_str);
    }

    fclose(fp);
}

int main() {
    station *sta;
    int i, stn_no;

    read_stn("station.dat", &sta, &stn_no);

    for (i = 0; i < stn_no; i++) {
        printf("%d %s %f %f\n", i + 1, sta[i].name, sta[i].lon, sta[i].lat);
    }

    free(sta);
    return 0;
}

outputs:

paul@local:~/src/c/scratch/station$ ./station
3
55.330002 44.270000 STN1
77.260002 33.439999 STN2
22.110001 23.120001 STN5
1 STN1 55.330002 44.270000
2 STN2 77.260002 33.439999
3 STN5 22.110001 23.120001
paul@local:~/src/c/scratch/station$

There are some other improvements you could make, eg you could fscanf() directly into double rather than via a float , you should check the return from fopen() and malloc() , and things like that, but I'll leave those as an exercise to you.

Also, for future reference, in your read_stn() function, it's often easier to create a local pointer, do all your work in that, and then assign the value to the output parameter just at the end. It helps you to avoid dealing with all this indirection within your function, for instance:

void read_stn(char filename[], station ** sta, int *station_no) {
    FILE *fp;
    station * psta;
    int st_num;

    if ( (fp = fopen(filename, "r")) == NULL ) {
        fprintf(stderr, "Couldn't open file %s\n", filename);
        exit(EXIT_FAILURE);
    }

    fscanf(fp, "%d", &st_num);
    printf("%d\n", st_num);

    if ( (psta = malloc(st_num * sizeof(*psta))) == NULL ) {
        fprintf(stderr, "Couldn't allocate memory\n");
        exit(EXIT_FAILURE);
    }

    for ( int i = 0; i < st_num; ++i ) {
        fscanf(fp, "%lf %lf %s", &psta[i].lon, &psta[i].lat, psta[i].name);
        printf("%f %f %s\n", psta[i].lon, psta[i].lat, psta[i].name);
    }

    *sta = psta;
    *station_no = st_num;

    fclose(fp);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM