You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将CSV分词字符串元素分配至结构体成员?代码问题排查

问题分析与修复方案

核心错误原因

你的代码中**i的递增顺序完全错位**,导致结构体成员的赋值逻辑和预期不符:
在token循环里,你先执行i++再判断i的值,第一个token处理时i从0变成1,直接进入i==1的分支给var1赋值,而ot1.time(对应i==0)永远没有被赋值的机会,后续var2、var3的对应关系也全部偏移。

此外还有几个次要问题:

  • 冗余的sleep函数和标准库重名,且无实际作用
  • fscanf("%s", line)无法读取包含空格的CSV行,建议改用fgets
  • strcpy存在缓冲区溢出风险

修复后的代码

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

struct ot{
    int time, var1;
    float var2;
    char var3[10];
};

int selection(){
    printf("1.start/resume 4.end\n");
    switch(getch()){
        case '1': //直接用字符常量更易读,避免ASCII码硬编码
            return 0;
        case '4':
            exit(0);
        default:
            return 1; //默认返回1,保持循环
    }
}

int main()
{
    struct ot ot1;
    const char *token;
    int i = 0, status;
    FILE *the_file = fopen("sample_data.csv", "r");
    if (the_file == NULL)
    {
        perror("unable to open the file");
        exit(1);
    }
    char line[2000];
    status = selection();
    
    //用fgets读取整行,替代fscanf避免空格截断问题
    while (fgets(line, sizeof(line), the_file) != NULL)
    {
        if (kbhit())
        {
            status = selection();
        }
        
        int delay_ms = 0;
        token = strtok(line, ",\n"); //把换行符也加入分隔符,避免行尾的换行被当作token
        
        i = 0; //每次处理新行前重置i
        while(token != NULL){
            printf("%s\n", token);
            
            //先根据当前i的值赋值,再递增i
            switch(i){
                case 0:
                    ot1.time = atoi(token);
                    delay_ms = ot1.time; //如果需要用第一个字段作为延迟时间
                    break;
                case 1:
                    ot1.var1 = atoi(token);
                    break;
                case 2:
                    ot1.var2 = atof(token);
                    break;
                case 3:
                    //用strncpy替代strcpy,避免缓冲区溢出,手动加终止符
                    strncpy(ot1.var3, token, sizeof(ot1.var3)-1);
                    ot1.var3[sizeof(ot1.var3)-1] = '\0';
                    break;
                default:
                    //处理多余的字段(可选)
                    printf("Warning: unexpected extra token: %s\n", token);
                    break;
            }
            
            i++;
            token = strtok(NULL, ",\n");
        }
        
        Sleep(delay_ms);
        system("cls");
        
        //打印结构体验证赋值结果
        printf("结构体赋值结果:\n");
        printf("time: %d\n", ot1.time);
        printf("var1: %d\n", ot1.var1);
        printf("var2: %.2f\n", ot1.var2);
        printf("var3: %s\n", ot1.var3);
    }
    
    fclose(the_file); //记得关闭文件
    return 0;
}

关键修改点

  1. 调整i的赋值逻辑:先根据当前i的值将token分配到对应结构体成员,再执行i++,确保第一个token对应i=0(ot1.time),第二个对应i=1(ot1.var1),以此类推。
  2. 替换fscanf为fgets:保证能读取包含空格的完整CSV行,同时把换行符加入strtok的分隔符,避免行尾的换行被误当作有效token。
  3. 安全处理字符串拷贝:用strncpy替代strcpy,并手动添加字符串终止符,防止var3缓冲区溢出。
  4. 移除冗余代码:删除无意义的sleep函数,优化selection函数的字符判断逻辑(直接用'1'、'4'替代ASCII码,可读性更强)。
  5. 添加文件关闭操作:避免资源泄漏。

测试建议

确保你的sample_data.csv每行格式符合预期,例如:

1000,123,45.67,test
2000,456,89.01,demo

运行程序后,就能看到每个token被正确分配到结构体的对应成员中。

内容的提问来源于stack exchange,提问作者Delwin Mathew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 09:10:44