c - 在循环中使用 scanf() 扫描 CSV 文件在第一行和第二行开始后停止

标签 c csv struct binary-search-tree

我需要读入一个巨大的 CSV 文件并将其存储在一个结构中,以插入到二叉搜索树中(但那是另一回事)但是我只能读取前四列(一行有四列) - 有任何想法吗?

预期输出:

Michael,21,M,12345
Susan,34,F,13342
Robin,12,F,45423
Teddy,43,M,56231
Ed,21,M,34354
Ramirez,21,F,79563
Toby,32,M,34277
Guy,23,M,90765
Desiree,21,F,67453
Molly,24,F,45434
Alison,23,F,62356
Tara,26,F,45223
Sally,21,F,34545
Mike,20,M,67676
Roger,19,M,83737
David,21,M,78554
Davis,23,M,66554
Sheng,22,M,31211
Wesley,31,M,21436

等,但我得到
Michael,21,M,12345
Susan

代码:
#include <stdlib.h>
#include <stdio.h>

#define MAXLEN 128

typedef struct{
    char name[MAXLEN];
    char age[MAXLEN];
    char sex[MAXLEN];
    char courseID[MAXLEN];
}input_t;

typedef struct{
    input_t input;
    struct bst *left;
    struct bst *right;
} bst;

void parse_csv(bst *node);
void print_csv(bst node);

void parse_csv(bst *node){
    while (scanf(" %[^,],%[^,],%[^,],%[^,]\n", node->input.name, node->input.age, node->input.sex, node->input.courseID) == 4) {
        break;
    }
}

void print_csv(bst node){
  printf("%s,%s,%s,%s\n",node.input.name, node.input.age, node.input.sex, node.input.courseID);
}

int main(int argc, char *argv[]) {
    bst node;
    parse_csv(&node);
    print_csv(node);
    return 0;
}

how the csv looks like, we will be given bigger test files to test on, though

最佳答案

这可以重复读取(假设格式是完美的,见下文);
虽然总是进入同一个节点。

while (scanf(" %[^,],%[^,],%[^,],%[^,]\n", 
       node->input.name,  
       node->input.age, 
       node->input.sex, 
       node->input.courseID) == 4) {

这破坏了乐趣,在第一次之后无条件停止。
    break;
}

“Susan”,这似乎意味着开始读取第二行,实际上是作为第一行的一部分读取的,因为格式说明符不合适,它允许读取任何非“,”的内容,包括换行符和 Susan。

在评论中,您确认更改 ,]\n -> ,\n]修复了行解析并为您提供正确扫描的第一行。

如果您还删除了 break ,扫描您的 CSV 应该可以工作。
“工作”如“读取所有 CSV,忽略大部分内容并仅存储最后一行”。为了显示多于一行,你当然需要
  • 一种可以存储多于一行的数据结构(可能是你的 BST)
  • 填写当前您的 BST break
  • print_csv()以某种方式显示整棵树

  • 或者
  • 调用 print_csv()以显示整棵树的方式

  • 另请参阅 Jonathan Leffler 在此答案的评论中的其他输入。
    他们指的是你所描述的“另一个故事”。

    作为旁注(乔纳森·莱夫勒也提到过):scanf() 可以处理格式完美且预期(可能生成)CSV 的这种用例。作为少数异常(exception)之一。对于任何对正确格式有丝毫怀疑的东西,最突出的是用户输入, scanf() 系列是不合适的,阅读整行并明确地进行容错解析是去那里的方法。
    但是,即使在预期输入格式完美的情况下,也要考虑恶意输入并通过限制扫描字段的长度来保护自己,以避免写入超出数组的范围,例如超越 char name[MAXLEN]或者char courseID[MAXLEN]取决于您的编译器如何安排结构。

    关于c - 在循环中使用 scanf() 扫描 CSV 文件在第一行和第二行开始后停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52050691/

    相关文章:

    arrays - 在 golang 中使用 neast 和数组创建高级结构

    c - MASM:从程序集访问全局 C 变量

    c - 为什么在此示例中我会收到带有 argv 的崩溃报告?

    c - 如何在 C 中的整数数组中选择(有效)随机相邻点?

    c - 在 C 中使用 malloc() 初始化大型数组时出现段错误

    php - 数据库值与数据流不匹配

    r - 如何将数据帧转换为时间序列?

    c - C 中的二维结构数组 - 如何声明和使用

    list - 检查nil指针取消引用的正确方法是什么?

    javascript - 数据安全图表