【问题标题】:Parsing CSV file into Structs using C使用 C 将 CSV 文件解析为结构
【发布时间】:2018-02-22 22:30:21
【问题描述】:

我正在尝试解析 CSV 文件并将值放入结构中,但是当我退出循环时,我只会返回文件的值。我不能使用 strtok,因为 csv 文件中的某些值是空的,它们会被跳过。我的解决方案是 strsep,当我在第一个 while 循环中时,我可以打印所有歌曲,但当我离开时,它只会返回文件的最后一个值。

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

#define BUFFSIZE 512

typedef struct song{
    char *artist;
    char *title;
    char *albumName;
    float duration;
    int yearRealeased;
    double hotttness;
} song;

typedef song *songPtr;

 int main(){
     FILE *songStream;
     int count = 0;
     int size = 100;
     char *Token;

     char *buffer;
     song newSong;
     songPtr currentSong;
     songPtr *allSongsArray = malloc(size * sizeof(songPtr));
     buffer = malloc(BUFFSIZE+1);

     songStream = fopen("SongCSV.csv", "r");

     if(songStream == NULL){
         err_sys("Unable to open file");
     }else{
         printf("Opened File");
             while(fgets(buffer, BUFFSIZE, songStream) != NULL){
                 char *line = buffer;
                 int index = 0;

                 while ((Token = strsep(&line,","))) {
                     if(index == 17){
                         newSong.title = malloc(sizeof(Token));
                         newSong.title = Token;
                     }
                     index++;
                 }
                 currentSong = malloc(1*sizeof(song));
                 *currentSong = newSong;
                 allSongsArray[count] = malloc(sizeof(currentSong) + 1);
                 allSongsArray[count] = &newSong;
                 free(currentSong);
                 printf("\n%s\n", allSongsArray[count]->title);
                 count++;

                 if(count == size){
                     size = size + 100;
                     allSongsArray = realloc(allSongsArray ,size * sizeof(songPtr));
                 }
             }
             fclose(songStream);
     }

     fprintf(stdout,"Name in struct pointer array:  %s\n",allSongsArray[2]->title);


     return 0;
 }

谁能告诉我为什么会发生这种情况以及如何解决它?

【问题讨论】:

    标签: c csv struct strsep


    【解决方案1】:

    您应该将newSong.title = Token; 更改为strcpy(newSong.title,Token); 因为Token 指向缓冲区中的一个地址,该地址将在读取下一行时保存新数据

    还可以避免内存泄漏

    newSong.title = malloc(sizeof(Token));
    

    将仅分配 sizeof(char *) 字节,因此您分配的字节数少于您需要的字节数,如果令牌超过 4 或 8 个字节,这可能会导致分段,具体取决于系统上的 sizeof(char *)

    p>
                 *currentSong = newSong; 
                 allSongsArray[count] = malloc(sizeof(currentSong) + 1); 
                 allSongsArray[count] = &newSong;
                 free(currentSong);
    

    改成

    memcpy(currentSong,&newSong,sizeof(newSong));
    allSongsArray[count] = currentSong;
    

    【讨论】:

    • 如何避免这个错误,我会在 newSong.title 上使用 malloc 还是 realloc?
    • 还有一些其他的更正,让我在回答中更新它们
    • 成功了,非常感谢您的帮助。为什么其他方式不起作用?
    • 您应该将标题分配给您认为令牌将保持最大值的足够字节
    • strlen代替sizeof来确定字符串的长度怎么样? (可能还有非标准的strlcpy
    猜你喜欢
    • 2017-10-26
    • 2011-11-17
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    相关资源
    最近更新 更多