【问题标题】:Error when trying to parse CSV data into a struct in C尝试将 CSV 数据解析为 C 中的结构时出错
【发布时间】:2021-10-13 02:18:17
【问题描述】:

我对 C 很陌生,但有一个大学作业要完成,所以请原谅这个问题的任何愚蠢之处。

我正在尝试将 CSV 解析为结构。当我运行以下代码时,我在编译时没有遇到任何问题,并且运行良好(尽管只打印出结果,并没有将它们分配给结构):

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

// Structs
struct Course {
    char *course_name[50];
    int grade;
};

struct Student {
    char* name;
    struct Course;
    int index;
};

char *dataArr[6] = {"Intro to Programming","Databases","Computer Architecture","Ethics in Computer Science","Advanced Programming","Puzzles and Problem Solving"};

// Expand this section for the initial interactivity
// =============================================================================================
void Import_and_Print()
{
    printf("\nPlace for importing files and printing results.\n\n");
    FILE * fp;
    char * line = NULL;
    size_t len = 0;
    ssize_t read;
    int in_grade;
    int i = 0;
    const char s[2] = ",";
    char *token;
    char *sName;
    int j;

    //fp = fopen("CTASample.csv", "r");
    fp = fopen("Sample2.csv", "r");
    if (fp == NULL)
        exit(EXIT_FAILURE);
    
    read = getline(&line, &len, fp);
    
    j = 0;
    
    while ((read = getline(&line, &len, fp)) != -1) {
        char *csvData = line;
        token = strtok(csvData,s);
        i = 0;
        
        while (token != NULL) {
            
            if (isalpha(token[0]) != 0) {
                strcpy(sName, token);
                printf("Student name: %s\n", sName); 
            }
            
            else {
                int in_grade = atoi(token);
                //printf("%0.f\n", in_grade);
                //printf("\n");
                printf("Course: %s\tGrade: %i\n", dataArr[i], in_grade);
                //struct Course course = {dataArr[i], in_grade};
                //struct Student name = {sName, {dataArr[i], in_grade}};
                i++;
                
            }
 
            token = strtok(NULL, s);

        fflush(stdin);
        }
        printf("\n\n");
    }  
}

但是,如果我将最后一个注释行更改为取消注释,我会收到以下错误:

Grades.c:在“Import_and_Print”函数中:Grades.c:64:60:警告: 从'int'初始化'char *'使指针来自整数 没有演员表[-Wint-conversion] 64 |结构 学生姓名 = {sName, {dataArr[i], in_grade}}; | ^~~~~~~~ Grades.c:64:60: 注意:(接近初始化为 ‘name..course_name[1]’)

csv 文件如下所示:

Intro to Programming,Databases,Computer Architecture,Ethics in Computer Science,Advanced Programming,Puzzles and Problem Solving
James Jameson,80,70,55,12,50,80
Peter Parker,50,55,50,50,50,50
Mary Janeson,40,40,40,23,40,45

关于如何解决的任何建议,以便将 csv 中的值正确输入到结构中?

【问题讨论】:

  • 旁白:注意fflush() 在打开输入的流上是未定义的。
  • 此外,else 代码块中定义的(已注释掉的)structs 将在块末尾超出范围。
  • 只是浏览数据和代码显示代码需要逗号 (,) 分隔符 (const char s[2] = ",") 而数据有管道分泌器 (|)...考虑更新程序中的分隔符... (const char s[2] = "|")
  • @Myst - 我编辑了 OP 以显示正确的输入。不知道为什么它显示管道,因为文件是逗号。

标签: c struct


【解决方案1】:

如果你正确格式化编译器错误,这个小小的“ASCII 艺术”^~~~~~~~ 是“这是你的错误”指示器,一个箭头通常指出错误的确切位置:

struct Student name = {sName, {dataArr[i], in_grade}};
|                                          ^~~~~~~~ 

在 C 中使用大括号进行嵌套初始化很棘手,因为该语言在大括号放置方面很松懈。在初始化所谓的 aggregates 时,我们应该始终使用大括号,这意味着容器类型,如数组和结构。

{dataArr[i], in_grade} 应该是结构的初始化列表,但该结构的第一个成员是一个数组,您没有用大括号括起来。

dataArr[i] 正确初始化数组中的第一个元素,因为它具有正确的类型char*,但随后编译器认为in_grade 用于初始化该数组中的第二项。因此“从‘int’初始化‘char *’”。

只需添加额外的大括号:

struct Student name = {sName, { {dataArr[i]}, in_grade}};

但是请注意,这个初始化列表仍然很奇怪和草率:它只初始化 course_name 数组的第一项,并没有显式初始化 index,因此它被隐式设置为零。

使代码更具可读性的“专业提示”是指定的初始化程序和适当的缩进:

struct Student name = 
{
  .name = sName, 
  .Course = 
  { 
    .course_name = { [0] = dataArr[i] }, // make it explicit that you init index 0 only
    .grade = in_grade,
  },
  .index = something;
};

【讨论】:

  • 谢谢。这非常简洁易懂。
猜你喜欢
  • 2014-09-09
  • 2018-05-16
  • 1970-01-01
  • 1970-01-01
  • 2018-02-22
  • 1970-01-01
  • 2022-10-01
  • 2023-03-03
  • 2021-09-20
相关资源
最近更新 更多