从CSV中阅读列并将其保存在C中的数组中不起作用,如何从数组中的所有值中删除引号

s5a0g9ez  于 2023-03-22  发布在  其他
关注(0)|答案(1)|浏览(94)

我必须将列1、2、4、5和14保存在数组中。我打印了这些列,这是输出。This is the output right now
因为我需要将列1和列14转换为浮点数组。我如何从所有列数组中删除引号?
the values in csv are saved and seperated by commas and quotes
This is the spreadsheet file

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

#define MAX_COLS 18  // Maximum number of columns in the CSV file
#define MAX_ROWS 211 // Maximum number of rows in the CSV file

int main() {
    char filename[] = "statscan_diabetes.csv";
    FILE *fp = fopen(filename, "r");
    if (fp == NULL) {
        printf("Error opening file %s\n", filename);
        return 1;
    }

    char line[1024];
    char *token;
    int row_count = 0;
    char ref_date[MAX_ROWS][11];
    char geo[MAX_ROWS][100];
    char age_group[MAX_ROWS][20];
    char sex[MAX_ROWS][10];
    char value_str[MAX_ROWS][10];
    float value[MAX_ROWS];

    // Read the header line and ignore it
    fgets(line, 1024, fp);

    // Read each line of the file and store values in arrays
    while (fgets(line, 1024, fp) != NULL && row_count < MAX_ROWS) {
        token = strtok(line, ",");
        int col_count = 0;
        while (token != NULL && col_count < MAX_COLS) {
            if (col_count == 0) {
                strcpy(ref_date[row_count], token);
            } else if (col_count == 1) {
                strcpy(geo[row_count], token);
            } else if (col_count == 3) {
                strcpy(age_group[row_count], token);
            } else if (col_count == 4) {
                strcpy(sex[row_count], token);
            } else if (col_count == 13) {
                strcpy(value_str[row_count], token);
                
            }
            token = strtok(NULL, ",");
            col_count++;
        }
        row_count++;
    }

  double ontario_total = 0, quebec_total = 0, bc_total = 0, alberta_total = 0;
    int ontario_count = 0, quebec_count = 0, bc_count = 0, alberta_count = 0;


//for (int i=0;i<=row_count;i++)
 // {
//if(geo[i]=="Quebec")
//{
//  quebec_total=quebec_total+
//}
    
//  }

 //  for (int i = 0; i < row_count; i++) {
//    printf("%s\n", value_str[i]);
 // }
  //Print the values stored in the arrays
   for (int i = 0; i < row_count; i++) {
      printf("%s %s %s %s %s\n", ref_date[i], geo[i], age_group[i], sex[i], value_str[i]);
   }

    fclose(fp);
    return 0;
}

起初我尝试使用浮点数组来存储第1列和第14列中的数字,并尝试打印它们,但输出结果显示所有值均为0.0。
我意识到,因为数字是由引号包围的,它也在阅读引号。
如何从所有数组中删除引号?

dfty9e19

dfty9e191#

如何删除所有列数组中的引号?
而不是strcpy(ref_date[row_count], token);,它有缓冲区溢出的风险并复制不需要的",调用一个帮助函数,让它跳过"并避免复制太多字符。

void copy_token(size_t size, char *dest, const char *source);

并调用它,并类似明智的其他令牌

copy_token(sizeof ref_date[row_count], ref_date[row_count], token);

下面的一个可能的实现只是简单地拼凑在一起。OP不清楚如果"缺少匹配",输入太长等等会发生什么。

void copy_token(size_t size, char *dest, const char *source) {
  if (size == 0) return;
  bool inside_quote = false;
  while (size > 1 && *source) {
    if (dest == '"') {
      inside_quote = !inside_quote;
    } else if (inside_quote) {
      *dest++ = *source;
      size--; 
    }
    source++;
  }
  *dest = '\0';
}

对于与float的对话,创建一个不同的帮助函数,跳过前导"(如果存在),调用strotd(),检查转换成功,查看尾随的非数字文本等。

float parse_token(const char *source);

OP代码的一个弱点是缺乏错误检测:行过长、标记过长、缺少""太多、float的非数字输入等。
对于初学者来说,这是可以容忍的,但是健壮的代码可以检测和处理错误的输入。帮助函数是分而治之以帮助实现这些目标的第一步。

相关问题