我有这段代码,它不会像它应该的那样工作。这个功能与另一个功能连接,我要求一个城市和一个日期。然后,在确认文件中存在两个之后,此函数将调用此新函数,如下所示。
我知道我不能将字符串与整数进行比较,我知道可以相互转换,但我不知道如何做,如果我能在这种情况下做到这一点。 id
是一个整数,meteo_city_id
是结构中存在的字符串。我在if
内的for
条件的第二部分中遇到此问题。
同时,在for
i < 152
,我有for
。这是我必须使用的文件中存在的行数。但是,用户可以在文件中添加行,因此,在添加新行之后,该代码将不再起作用。那么我可以替换152以便循环#define TAM_STR 100
typedef struct city_t{
char city_id[TAM_STR];
char city_name[TAM_STR];
char county_name[TAM_STR];
char district_name[TAM_STR];} city_t;
typedef struct meteo_t{
char meteo_id[TAM_STR];
char meteo_city_id[TAM_STR];
char tempt_max[TAM_STR];
char tempt_min[TAM_STR];
char humidity[TAM_STR];
char pressure[TAM_STR];
char date[11];} meteo_t;
city_t *read_meteo(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", "meteo.csv", strerror(errno));
return NULL;
}
meteo_t *arr = NULL, *tmp;
*len = 0;
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", "meteorologia.csv");
if(*len == 0)
{
free(arr);
arr = NULL;
}
return arr;
}
arr = tmp;
sscanf(line, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%s", (arr[*len].meteo_id), (arr[*len].meteo_city_id), (arr[*len].tempt_max), (arr[*len].tempt_min), (arr[*len].humidity), (arr[*len].preassure), (arr[*len].date));
(*len)++;
}
fclose(fp);
if(*len == 0)
{
free(arr);
arr = NULL;
}
return arr;
}
void search_meteo_by_city_by_date(meteo_t *meteo, size_t len, const char *city, const int id, const char *date){
bool find = false;
if(meteo == NULL || city == NULL || id == NULL || date == NULL) {
printf("ERROR");
}
for(size_t i = 0; i < 152; ++i) {
if (strcasecmp(date, meteo[i].date) == 0 && id == meteo[i].meteo_city_id) {
find = true;
printf("Information for: %s in %s \nMaximum Temperature: %s ºC\nMinimum Temperature: %s ºC\nHumidity: %s \nPressure: %s hPa\n\n\n", city, date, meteo[i].tempt_max, meteo[i].tempt_min, meteo[i].humidity, meteo[i].preassure);
}
}
if(find == false) {
printf("No results were found for: %s\n", city);
}
}
void search_date_by_city() {
size_t cities_len;
city_t *cities = read_cities("cities.csv", &cities_len);
char local[100];
char date[100];
// error
if(cities == NULL) {
printf("ERROR");
}
printf("City: ");
scanf("%[^\n]%*c", local);
int id = search_for_city_by_name(cities, &cities_len, cidade);
if(id == -1) {
printf("That city doesn't exist\n");
return;
}
printf("Date: ");
scanf("%[^\n]%*c", date);
size_t meteo_len;
meteo_t *meteo = read_meteo("meteo.csv", &meteo_len);
if(meteo == NULL) {
printf("ERROR");
}
search_meteo_by_city_by_date(meteo, &meteo_len, local, id, date);
工作,而不管以后添加的行数是多少?
谢谢您的帮助。这是功能:
id,city,county,district
}
文件cities.csv有152行和4列,例如
meteo_id,meteo_city_id,tempt_max,tempt_min,humidity,pressure,date
文件meteo.csv有152行和7个cloumns,例如
[
{
"one": 37,
"two": "2017-09-15T19:31:55"
}
]
答案 0 :(得分:2)
函数:search_meteo_by_city_by_date()
期望参数len
包含实际的条目数。但是,在调用该函数的地方,传递的是包含该函数的变量的ADDRESS实际的参赛人数。
建议替换这个:
search_meteo_by_city_by_date(meteo, &meteo_len, local, id, date);
用这个:
search_meteo_by_city_by_date(meteo, meteo_len, local, id, date);
传递metro_len
的内容而不是metro_len
然后替换它:
for(size_t i = 0; i < 152; ++i)
与
for(size_t i = 0; i < len; ++i)
答案 1 :(得分:1)
所以你需要知道文件中的行数。你能简单地计算换行数或回车数吗?
我看不到你对read_meteo的实现,但我认为你可以在那里添加一些计算文件中行数的东西。
此外,atoi()可能有助于将字符串数转换为int。
答案 2 :(得分:1)
始终在启用所有警告的情况下进行编译。
如果你这样做了,你会发现这样的事情:
In function ‘read_meteo’:
test.c:51:16: warning: return from incompatible pointer type [-Wincompatible-pointer-types]
return arr;
^~~
error: ‘meteo_t {aka struct meteo_t}’ has no member named ‘preassure’;
did you mean ‘pressure’?
sscanf(line, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%s",
(arr[*len].meteo_id), (arr[*len].meteo_city_id), (arr[*len].tempt_max),
(arr[*len].tempt_min), (arr[*len].humidity), (arr[*len].preassure),
(arr[*len].date));
warning: comparison between pointer and integer
if (strcasecmp(date, meteo[i].date) == 0 && id == meteo[i].meteo_city_id) {
^~
warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
meteo_t *meteo = read_meteo("meteo.csv", &meteo_len);
^~~~~~~~~~
warning: passing argument 2 of ‘search_meteo_by_city_by_date’
makes integer from pointer without a cast [-Wint-conversion]
search_meteo_by_city_by_date(meteo, &meteo_len, local, id, date);
^~~~~~~~~~
note: expected ‘size_t {aka long unsigned int}’ but argument
is of type ‘size_t * {aka long unsigned int *}’
void search_meteo_by_city_by_date(meteo_t *meteo, size_t len,
^~~~~~~~~~~
const char *city, const int id, const char *date){
只需将152
替换为len
即可。显然你已经有了一个数组索引计数器:
meteo_t *meteo = read_meteo("meteo.csv", &meteo_len);
if (meteo == NULL) {
printf("ERROR");
// YOU SHOULD ALSO EXIT IF YOU EVER ENTER HERE.
}
search_meteo_by_city_by_date(meteo, &meteo_len, cidade, id, date);
以上,正如@ user3629249指出的那样,在逻辑上是正确的但是正式不正确因为传递的参数是而不是该值(可能是152,所以正确)但其地址,几乎肯定不是152,因此非常不正确。这就是为什么当你应用这个解决方案时,你会崩溃。
如果您已激活编译器警告,则此错误不会出现,如果我,我相信我会给出正确的(但仍未完成!看看上面的那些问题!)回答。由于我们都没有使用警告,你和我都错了。所以:使用编译器警告。