gpt4 book ai didi

c - 使用结构从文件 I/O 读取然后打印的问题

转载 作者:行者123 更新时间:2023-11-30 16:35:55 25 4
gpt4 key购买 nike

我正在尝试读取一个 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

谁能帮我解决这个问题吗?

最佳答案

你的代码很奇怪,用你发布的代码你不应该能够写任何东西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;
}

以及免费功能:

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

关于c - 使用结构从文件 I/O 读取然后打印的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48696652/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com