pm25_avg_sort.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /** pm25_avg_sort.c
  2. 读取 pm25 文件内容,统计每个城市 2022-01 ~ 2022-05 的平均 PM2.5 并排序
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. const char *MIN_MONTH = "2022-01-01";
  8. const char *MAX_MONTH = "2022-05-01";
  9. //使用结构体来存储一个城市的 PM25 值
  10. typedef struct{
  11. char* city;
  12. int pm25;
  13. } CityPM25;
  14. int split (const char *txt, char delim, char ***tokens){
  15. int *tklen, *t, count = 1;
  16. char **arr, *p = (char *) txt;
  17. while (*p != '\0') if (*p++ == delim) count += 1;
  18. t = tklen = calloc (count, sizeof (int));
  19. for (p = (char *) txt; *p != '\0'; p++) *p == delim ? *t++ : (*t)++;
  20. *tokens = arr = malloc (count * sizeof (char *));
  21. t = tklen;
  22. p = *arr++ = calloc (*(t++) + 1, sizeof (char *));
  23. while (*txt != '\0'){
  24. if (*txt == delim){
  25. p = *arr++ = calloc (*(t++) + 1, sizeof (char *));
  26. txt++;
  27. }
  28. else *p++ = *txt++;
  29. }
  30. free (tklen);
  31. return count;
  32. }
  33. int compare_pm25(const void* arg1, const void* arg2){
  34. const CityPM25 *a = (const CityPM25*) arg1;
  35. const CityPM25 *b = (const CityPM25*) arg2;
  36. if (a->pm25 < b->pm25) return -1;
  37. if (a->pm25 > b->pm25) return 1;
  38. return 0;
  39. }
  40. int main(int argc, char** argv){
  41. char *filename = "../pm25/PM25_By_Cities.csv";
  42. FILE* fp = fopen(filename, "r");
  43. if(!fp){
  44. fprintf(stderr, "Cannot open file.\n");
  45. exit(1);
  46. }
  47. char *line = NULL;
  48. size_t linecap = 0; // line capacity
  49. ssize_t read;
  50. CityPM25 *cities_pm25 = calloc(12, sizeof(CityPM25));
  51. char *city = NULL;
  52. int data_count = 0;
  53. long total_pm25 = 0L;
  54. int index = 0;
  55. while ((read = getline(&line, &linecap, fp)) > 0){
  56. char **tokens;
  57. int count, i;
  58. count = split (line, ',', &tokens);
  59. if(count >= 7) {
  60. char *current_city = tokens[0];
  61. char *month = tokens[1];
  62. char *pm25 = tokens[5];
  63. if(city==NULL) city = current_city;
  64. // 同一个城市,且月份在最小月份(1月)到最大月份(5月)之间:
  65. if(strcmp(current_city, city)==0 &&
  66. strcmp(month, MIN_MONTH) >= 0 &&
  67. strcmp(month, MAX_MONTH) <=0 ){
  68. data_count++;
  69. total_pm25 += atoi(pm25);
  70. if(strcmp(month, MAX_MONTH) == 0){
  71. int *average = (int *) malloc(sizeof(int));
  72. *average = total_pm25/data_count;
  73. printf("City:%s average pm2.5:%d\n", city, *average);
  74. CityPM25 *current_city_pm25 = (CityPM25 *) malloc(sizeof(CityPM25));
  75. current_city_pm25 -> city = city;
  76. current_city_pm25 -> pm25 = *average;
  77. cities_pm25[index++] = *current_city_pm25;
  78. }
  79. }else {
  80. //重新开始统计新城市的数据
  81. city = current_city;
  82. data_count = 0;
  83. total_pm25 = 0L;
  84. }
  85. //printf ("City:%s month:%s pm2.5:%s\n", city, month, pm25);
  86. }
  87. /* FIXME: freeing tokens */
  88. //for (i = 0; i < count; i++) free (tokens[i]);
  89. //free (tokens);
  90. }
  91. qsort(cities_pm25, index, sizeof(CityPM25), compare_pm25);
  92. printf("\nSorted PM2.5 for each city, %s - %s:\n", MIN_MONTH, MAX_MONTH);
  93. while(cities_pm25 && cities_pm25->city){
  94. printf("city:%s pm2.5:%d \n", cities_pm25 ->city, cities_pm25 -> pm25);
  95. cities_pm25++;
  96. }
  97. fclose(fp);
  98. if (line)
  99. free(line);
  100. return 0;
  101. }