我正在尝试读取一个CSV文件,并打印出所述文件中的选择值,所有这些字符串(最后都有一个字符),而我实际上无法将其打印出来。它应该忽略输入中的特定数据,如ASO,ORL,PR
,当然也可以跳过空白区域。我不知道文件I / O是否有问题,或者我打错了。有人可以帮忙吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct airdata{
char *siteNum;
char *LocalID;
char *portName;
char *city;
char *state;
char *lat;
char *lon;
char Tower;
} airdata;
int main(){
FILE * fin = fopen("florida.csv", "rw");
if((fin = fopen("florida.csv", "r")) == NULL){
printf("etl ERROR: File inputFile not found.\n");
return(0);
}
printf("\nFile opened successfully\n\n");
printf("%-12s %-11s %-42s %-34s %-3s %-15s %-16s Tower\n",
"FAA Site", "Short Name", "Airport Name", "City", "ST",
"Latitude", "Longitude");
printf("%-12s %-11s %-42s %-34s %-3s %-15s %-16s =====\n",
"========", "==========", "============", "====", "==",
"========", "=========");
char buffer[1000];
while(fscanf(fin, "%s", buffer) != EOF){
airdata * entry = malloc(sizeof(airdata));
fprintf(fin, "%s%s%s%s%s%*s%*s%*s%s%s%*s%*s%c%*s%*s", entry->siteNum, entry->LocalID,
entry->portName, entry->city, entry->state, entry->lat, entry->lon, entry->Tower);
printf("%s%s%s%s%s%*s%*s%*s%s%s%*s%*s%c%*s%*s", entry->siteNum, entry->LocalID,
entry->portName, entry->city, entry->state, entry->lat, entry->lon, entry->Tower);
}
fclose(fin);
}
这是输入和输出
IN:
03010.1*A,63FD,LINK FIELD,ALACHUA,FL,ASO,ORL,PR,29-41-53.0000N,082-29-29.0000W,PR,,NON-NPIAS,,N,,,2,0
OUT:
03010.1*A 63FD LINK FIELD ALACHUA FL 29-41-53.0000N 082-29-29.0000W N
任何人都可以帮我吗?
答案 0 :(得分:0)
您的代码很奇怪,使用您发布的代码,您不应该写任何内容
fin
,因为你打开它只是为了阅读。
FILE * fin = fopen("florida.csv", "rw");
if((fin = fopen("florida.csv", "r")) == NULL)
...
您打开一次进行读/写,然后使用相同的FILE*
重新打开它
变量,读/写句柄丢失。 fprintf(fin, ...)
来电应该
返回-1。
第二个问题是:
while(fscanf(fin, "%s", buffer) != EOF){
airdata * entry = malloc(sizeof(airdata));
fprintf(fin, "%s%s%s%s%s%*s%*s%*s%s%s%*s%*s%c%*s%*s", entry->siteNum, entry->LocalID,
entry->portName, entry->city, entry->state, entry->lat, entry->lon, entry->Tower);
printf("%s%s%s%s%s%*s%*s%*s%s%s%*s%*s%c%*s%*s", entry->siteNum, entry->LocalID,
entry->portName, entry->city, entry->state, entry->lat, entry->lon, entry->Tower);
}
您在每个循环中为airdata
对象分配内存,但它总是如此
没有初始化,所以当你打印成员时你会得到垃圾。此外fin
仅供阅读,
写操作将失败。你也没有释放记忆,所以你是
在循环迭代中泄漏内存。最后你不检查是否malloc
返回NULL
。
请注意fscanf
来电只会告诉您下一个字,而不是整行,
这是因为%s
匹配一系列非空白字符。
您在问题中向我们展示的输出无法使用您的代码。
无论如何,您应该以不同的方式进行解析。阅读整行
使用fgets
,然后使用strtok
获取值:
int main(void)
{
airdata **entries = NULL, **tmp;
size_t num_of_entries = 0;
char buffer[1024];
const char *delim = ",\r\n";
while(fgets(buffer, sizeof buffer, fin))
{
tmp = realloc(entries, sizeof *entries);
if(tmp == NULL)
{
// one possible error handling
fclose(fin);
free_airdata_array(entries, num_of_entries);
return 1;
}
entries = tmp;
airdata *data = calloc(1, sizeof *data);
if(data == NULL)
{
fclose(fin);
free_airdata_array(entries, num_of_entries);
return 1;
}
// parsing
char **params[] = {
&data->siteNum,
&data->LocalID,
&data->portName,
&data->city,
&data->state,
&data->lat,
&data->lon,
};
char *input = buffer, *token;
for(size_t i = 0; i < sizeof params / sizeof *params; ++i)
{
token = strtok(input, delim);
if(token == NULL)
{
flcose(fin);
free_airdata_array(entries, num_of_entries);
free_airdata(data);
return 1;
}
*params[i] = strdup(token);
if(*params[i] == NULL)
{
flcose(fin);
free_airdata_array(entries, num_of_entries);
free_airdata(data);
return 1;
}
input = NULL; // subsequent calls of strtok expect NULL
}
token = strtok(NULL, delim);
if(token == NULL)
data->Tower = 0;
else
data->Tower = *token;
entries[num_of_entries++] = data;
}
fclose(fin);
do_something_with_the(entries, num_of_entries);
free_airdata_arra(entries);
return 0;
}
free
函数:
void free_airdata_array(airdata **array, size_t num_of_entries)
{
if(array == NULL)
return;
for(size_t i = 0; i < num_of_entries; ++i)
free_airdata(array[i]);
free(array);
}
void free_airdata(airdata *data)
{
if(data == NULL)
return;
char **params[] = {
&data->siteNum,
&data->LocalID,
&data->portName,
&data->city,
&data->state,
&data->lat,
&data->lon,
};
for(size_t i = 0; i < sizeof params / sizeof *params; ++i)
free(*params[i]);
free(data);
}
如果您的系统没有strdup
:
char *strdup(const char *text)
{
if(text == NULL)
return NULL;
char *ret = malloc(strlen(text) + 1);
if(ret == NULL)
return NULL;
return strcpy(ret, text);
}