2013-10-05 66 views
2

這是我的新問題,因爲我是如此新手!!! :)在函數中設置指針的pterter指針的成員

我有這樣一個文本文件:

3 
55.33 44.27 STN1 
77.26 33.44 STN2 
22.11 23.12 STN5 

我想在C閱讀。

所以我已經在文件頭定義的結構賦予read_stn.h對於像文件:

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

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

並嘗試使用以下代碼

#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); 
} 

和主程序讀取文件:

#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; 
} 

但是當我試圖讀取文件時,我得到了分段核心轉儲。我的文件中是否有錯誤?我認爲在定義指針成員賦值的指針時出現錯誤。你能幫我嗎?

回答

4

你並不遙遠,有幾個錯誤。

此:

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

應該是這樣的:

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

,因爲你要幾個結構分配內存,而不是幾個結構指針。

那麼這個:

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

應該是:

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

因爲你的動態數組存儲在*sta,而不是在sta

完整的工作版本:

#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; 
} 

輸出:

[email protected]:~/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 
[email protected]:~/src/c/scratch/station$ 

還有一些其他方面的改進,你可以做,例如你可以直接將fscanf()分配給double而不是通過float,你應該檢查fopen()malloc()的回報,以及類似的事情,但我將把這些作爲練習留給你。另外,爲了將來的參考,在你的read_stn()函數中,創建一個本地指針,完成所有工作,然後在最後將值分配給輸出參數通常更容易。它可以幫助你避免你的函數中這一切的間接處理,例如:

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); 
} 
+1

+1,爲全面解決整個問題 – fayyazkl

+0

非常感謝您 –

+0

不客氣,很好的問題,這是一個典範[SSCCE](http://sscce.org/)。 –