将整数转换/比较为C中的字符串,并将'中的错误转换为'循环

时间:2018-02-17 16:36:52

标签: c

我有这段代码,它不会像它应该的那样工作。这个功能与另一个功能连接,我要求一个城市和一个日期。然后,在确认文件中存在两个之后,此函数将调用此新函数,如下所示。 我知道我不能将字符串与整数进行比较,我知道可以相互转换,但我不知道如何做,如果我能在这种情况下做到这一点。 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"
  }
]

3 个答案:

答案 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,因此非常不正确。这就是为什么当你应用这个解决方案时,你会崩溃。

如果您已激活编译器警告,则此错误不会出现,如果,我相信我会给出正确的(但仍未完成!看看上面的那些问题!)回答。由于我们都没有使用警告,你和我都错了。所以:使用编译器警告