这是我的新问题,因为我是新手! :)
我有一个文本文件,如:
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;
}
但是当我尝试读取文件时,我得到了分段核心转储。我的文件中是否有任何错误。我认为定义指针成员分配的指针有一些错误。你能帮助我吗?
答案 0 :(得分: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;
}
输出:
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$
您可以进行一些其他改进,例如:你可以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);
}