gpt4 book ai didi

c - 如何在 C 中编辑 .csv 文件

转载 作者:太空宇宙 更新时间:2023-11-04 04:18:48 25 4
gpt4 key购买 nike

我是编程新手,我的 C 项目需要帮助。我必须搜索一个城市,确认它存在于第一个文件 (city.csv) 中,然后从那里获取它的 ID。然后我必须将该 ID 与第二个文件 (meteo.csv) 中的相应 ID 进行匹配,然后编辑其天气信息,即在第二个文件中。但是,我不知道如何从第一个文件中获取城市 ID,然后在获取所有新的天气信息后如何编辑第二个文件。这是代码:

void addInfo() {
FILE * fp;
char id_city[100];
char city[100];
char humidity[100];
char temp_max[100];
char temp_min[100];
char pressure[100];
char date[100];

printf("Name of the city: ");
scanf("%s", city);


// I think it's here that I have to write the code for take the city's id from the first file

if (id_city != NULL) {
printf("Maximun temperature: ");
scanf("%s", temp_max);
printf("Minimun temperature: ");
scanf("%s", temp_min);
printf("Humidity: ");
scanf("%s", humidity);
printf("Pressure: ");
scanf("%s", pressure);
printf("Date, in the format YYYY-MM-DD: ");
scanf("%s", date);

fp = fopen ("meteo.csv", "a");
fprintf(fp, "%s, %s, %s, %s, %s \n", temp_max, temp_min, humidity, pressure, date); //I think there's something wrong here too...

fclose(fp);
printf("Information edited successfully");

}

文件 city.csv 有 152 行和 4 列:

(id_city,city,county,district)

比如

(56,Lisbon,Lisbon,Lisbon)

文件 meteo.csv 有 152 行和 7 列:

(id_meteo_city,id_city,temp_max,temp_min,humidity,pressure,date) 

比如

(56,56,14,5,62,1025,2018-02-12)

最佳答案

我要做的第一件事是将数据封装在 struct 中,这样就可以了更容易将 CSV 文件的一行映射到表示一行的对象。

如果文件 city.csvmeteo.csv 都有不同的列,我会创建一个每个文件都有不同的struct。如果两个文件有相同的列,你可以使用结构。我假设这两个文件是不同的并且 city 有格式 meteo_id,city_id,name.

typedef struct city_t {
int meteo_id;
int city_id;
char name[100]; // no city should have
// longer than 100 chars
} city_t;

typedef struct meteo_t {
int meteo_id;
int city_id;
int tempt_max;
int tempt_mix;
double humidity;
double preassure;
char date[11];
} meteo_t;

假设两个文件的格式都正确,否则您将不得不编写检查错误并处理错误的代码,这将是下一步在练习中,所以我打算只写有基本错误的基本版本认可。

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

// takes 2 params, the filename and a pointer
// to size_t where the number of cities is stored
city_t *read_cities(const char *filename, size_t *len)
{
if(filename == NULL || len == NULL)
return NULL;

FILE *fp = fopen(filename, "r");
if(fp == NULL)
{
fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno));
return NULL;
}

city_t *arr = NULL, *tmp;
*len = 0;

// assuming that no line will be longer than 1023 chars long
char line[1024];

while(fgets(line, sizeof line, fp))
{
tmp = realloc(arr, (*len + 1) * sizeof *arr);
if(tmp == NULL)
{
fprintf(stderr, "could not parse the whole file %s\n", filename);
// returning all parsed cities so far

if(*len == 0)
{
free(arr);
arr = NULL;
}

return arr;
}

arr = tmp;

// %99[^\n] is to read up to 99 characters until the end of the line
if(sscanf(line, "%d,%d,%99[^\n]", &(arr[*len].meteo_id),
&(arr[*len].city_id), arr[*len].name) != 3)
{
fprintf(stderr, "Invalid line format (skipping line):\n%s\n", line);
// skip this line, and decrement *len
(*len)--;
continue;
}

// incrementing only when parsing of line was OK
(*len)++;
}

fclose(fp);

// file is empty or
// all lines have wrong format
if(*len == 0)
{
free(arr);
arr = NULL;
}


return arr;
}

void print_cities(city_t *cities, size_t len, FILE *fp)
{
if(cities == NULL || fp == NULL)
return;

for(size_t i = 0; i < len; ++i)
fprintf(fp, "%d,%d,%s\n", cities[i].meteo_id, cities[i].citiy_id,
cities[i].name);
}

现在我已经为文件 citiy.csv 编写了读写函数,假设格式 meteo_id;city_id;nameprint_cities 允许您打印 CSV屏幕上的内容(将 stdout 作为最后一个参数传递)或文件(将 FILE 对象作为最后一个参数传递)。

您可以使用这些函数作为模板来读写meteo.csv,想法是一样的。

您可以按如下方式使用这些功能:

int main(void)
{
size_t cities_len;
city_t *cities = read_cities("city.csv", &cities_len);

// error
if(cities == NULL)
return 1;

do_something_with_cities(cities, cities_len);

// update csv
FILE *fp = fopen("city.csv", "w");

if(fp == NULL)
{
fprintf(stderr, "Could not open city.csv for reading: %s\n",
strerror(errno));

free(cities);
return 1;
}

print_cities(cities, cities_len, fp);

fclose(fp);
free(cities);
return 0;
}

现在开始练习:编写一个类似的函数来解析 meteo.csv(使用我作为模板的功能不应该那么困难)并解析这两个文件。现在你把它们放在内存中,就很容易操作数据(插入,更新、删除)。然后像我在示例中所做的那样编写文件,就是这样。

最后一个提示:如何搜索城市:

// returns the index in the array or -1 on error or when not found
int search_for_city_by_name(city_t *cities, size_t len, const char *name)
{
if(cities == NULL || name == NULL)
return -1;

for(size_t i = 0; i < len; ++i)
if(strcmp(name, cities[i].name) == 0)
return i;

// not found
return -1;
}

现在我已经把作业的几乎所有部分都交给了你,你所要做的就是将它们粘在一起并为 meteo.csv 文件编写相同的函数。

关于c - 如何在 C 中编辑 .csv 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48793728/

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