Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
读取、解析csv文件,填充结构,然后将结构写入数据文件_C_File Io_Struct - Fatal编程技术网

读取、解析csv文件,填充结构,然后将结构写入数据文件

读取、解析csv文件,填充结构,然后将结构写入数据文件,c,file-io,struct,C,File Io,Struct,我正在编写一个程序,它读取和解析CSV文件,用CSV文件的内容填充结构,然后以二进制模式将结构写入文件。我通过标记csv文件并将每个标记写入结构来解析它。 问题是,当我尝试将此结构写入数据文件时,文件内容会显示一些特殊字符,即它写入任何随机值。我正在附加output.dat文件。 有人能帮我找到我错的地方吗?谢谢 这是我的密码: typedef struct { int AccountNumber; char *AccountName; double

我正在编写一个程序,它读取和解析CSV文件,用CSV文件的内容填充结构,然后以二进制模式将结构写入文件。我通过标记csv文件并将每个标记写入结构来解析它。 问题是,当我尝试将此结构写入数据文件时,文件内容会显示一些特殊字符,即它写入任何随机值。我正在附加output.dat文件。 有人能帮我找到我错的地方吗?谢谢

这是我的密码:

typedef struct  
{
    int AccountNumber;  
    char    *AccountName;  
    double  AccountBalance;  
    double  LastPaymentAmount;  
    char    *LastPaymentDate;  
} Person;

FILE    *fpData;        

Person temp = {0,"",0,0,0};

if ( ( fpData = fopen( "input.csv", "r" ) ) == NULL ) //Reading a file
{
    printf( "File could not be opened.\n" );
}

while(fgets(buf, BUFFER_SIZE, fpData) != NULL)
{
    /* Here we tokenize our string and scan for " \n" characters */

    // for(tok = strtok(buf,"\n");tok;tok=strtok(NULL,"\n"))
    // {
        tok = strtok(buf, ",");
        temp.AccountNumber = atoi(tok); 
        printf(" %i ",temp.AccountNumber );

        tok = strtok(NULL, ",");

        temp.AccountName = tok;
        printf("%s ",temp.AccountName );

        tok = strtok(NULL, ",");

        temp.AccountBalance = atof(tok);
        printf("temp.AccountBalance = %f ",temp.AccountBalance );

        tok = strtok(NULL, ",");

        temp.LastPaymentAmount = atof(tok);
        printf("temp.LastPaymentAmount = %f ",temp.LastPaymentAmount );

        tok = strtok(NULL, ",");

        temp.LastPaymentDate = tok;  
        printf("temp.LastPaymentDate = %s ",temp.LastPaymentDate );

        tok = strtok(NULL, ",");
        printf("\n");                 
    // }  
}

if ( ( fpData = fopen( "output.dat", "wb" ) ) == NULL )  
{  
   printf( "File could not be opened.\n" );  
}  
else  
{  
    printf("\nFileName is:%s\n",argv[2]);  
    printf("File will be overwritten. Do you want to continue?\nPress Y if yes, N if no");  
    printf("\n?\n");  
    scanf("%c", &choice);  

    if(choice=='Y')         
    {  
        for(i=0;i<10;i++)  
        {  
            fwrite(&temp, sizeof(temp), 10, fpData);  
        }           
    }  
}  

fclose(fpData);
typedef结构
{
国际帐户号码;
字符*帐户名;
双重账户余额;
双倍的最后付款金额;
char*LastPaymentDate;
}人;
文件*fpData;
Person temp={0,”,0,0,0};
if((fpData=fopen(“input.csv”,“r”))==NULL)//读取文件
{
printf(“无法打开文件。\n”);
}
while(fgets(buf,BUFFER_SIZE,fpData)!=NULL)
{
/*在这里,我们标记字符串并扫描“\n”字符*/
//对于(tok=strtok(buf,“\n”);tok;tok=strtok(NULL,“\n”))
// {
tok=strtok(buf,“,”);
温度账户编号=atoi(tok);
printf(“%i”,临时帐号);
tok=strtok(空,“,”);
temp.AccountName=tok;
printf(“%s”,临时帐户名);
tok=strtok(空,“,”);
温度账户余额=atof(tok);
printf(“临时账户余额=%f”,临时账户余额);
tok=strtok(空,“,”);
临时最后付款金额=atof(tok);
printf(“temp.LastPaymentAmount=%f”,temp.LastPaymentAmount);
tok=strtok(空,“,”);
temp.LastPaymentDate=tok;
printf(“temp.LastPaymentDate=%s”,temp.LastPaymentDate);
tok=strtok(空,“,”);
printf(“\n”);
// }  
}
if((fpData=fopen(“output.dat”、“wb”))==NULL)
{  
printf(“无法打开文件。\n”);
}  
其他的
{  
printf(“\n文件名为:%s\n”,argv[2]);
printf(“文件将被覆盖。是否继续?\N如果是,请按Y;如果否,请按N”);
printf(“\n?\n”);
scanf(“%c”,选择(&c));
如果(选项=='Y')
{  

对于(i=0;i如果不在结构中定义一个静态数组来存储字符串,我认为这是行不通的,当前,当您将结构写入磁盘时,只有指针被写入。

您没有为试图复制到输出文件中的结构数组以及字符数组分配任何内存结构中的成员。仅复制从
strtok()
返回的指针将不起作用,因为该指针指向
strtok()中的静态字符数组
函数。因此,基本上,在一次通过while循环后,
temp.AccountName
temp.LastPaymentDate
都指向同一个确切的内存位置。此外,正如上面chemuduguntar指出的,当您写出结构时,您只写出内存指针……没有实际的内存字符串数据在您的结构中,假设是字符数组

您有两种选择…要么使用静态存储声明结构以存储字符串数组,然后使用
strcpy()
将数据从
strtok()
复制到这些数组中,要么使用
malloc()
为指针分配内存(请记住,除非您希望内存泄漏,否则以后必须释放这些指针)

比如说,你可以这样做:

#define MAXBUFSIZE 511

typedef struct  
{
    int AccountNumber;  
    char AccountName[MAXBUFSIZE + 1];  
    double AccountBalance;  
    double LastPaymentAmount;  
    char LastPaymentDate[MAXBUFSIZE + 1];  
} Person;
然后在while循环中,当您调用
strtok()
时,可以执行以下操作:

tok = strtok(NULL, ",");
strncopy(temp.AccountName, tok, MAXBUFSIZE);
temp.AccountName[MAXBUFSIZE] = '\0'; //safety NULL termination

//...more code

tok = strtok(NULL, ",");
strncopy(temp.LastPaymentDate, tok, MAXBUFSIZE);
temp.LastPaymentDate[MAXBUFSIZE] = '\0'; //safety NULL termination
现在,使用这种方法,结构中的实际数据并不指向某个地方的临时存储…这种方法的唯一缺点是,如果超过512字节,则会剪裁该数据。如果低于512字节,则会在字符数组的末尾填充全零

接下来,您需要在某个地方声明:

Person myarray[10];

因为现在每次执行while循环时,都会过度写入先前的
temp
值。因此,在某个时候,您需要将
temp
结构复制到更永久的存储阵列中。例如,在while循环结束时,您应该调用:

memcpy(&myarray[LOOPNUMBER], &temp, sizeof(Person)); 
最后,对于对fwrite()的调用,我将稍微更改一下,使其类似于:

for(i=0;i<10;i++)  
{  
    fwrite(myarray, sizeof(Person), 10, fpData);  
} 

对于(i=0;i您似乎缺少一些代码…1)您只分配了
Person
的一个实例,即堆栈上的变量
temp
——堆上不应该有一个数组或某种类型的内存指针指向一个
Person
结构的数组,并将每次从文件读取的内容保存到其中吗?2)
buf
的分配在哪里?缓冲区大小的定义是什么?3)我假设所有调试信息都正确打印出来(即,您实际上正确地标记了文件)?是的。标记化是用CSV文件中的10个条目正确填充结构。但当我将其写入文件时,它只会用一些特殊字符写入最后一个条目。请注意,为CVS提供的定义比您的标记化程序所能处理的更复杂。如果保证输入以您的cod的简单形式进行,那就不会是一场灾难e是预期的,但如果您将从符合RFC 4180的源接收数据,则可能会出现问题。请参阅。谢谢。但您能帮助我将结构写入文件吗?
for(i=0;i<10;i++)  
{  
    fwrite(myarray, sizeof(Person), 10, fpData);  
}