将csv文件中的数据读取到结构中,并返回错误
我正在尝试将csv文件中的数据读取到结构中。结构包含int、char和float成员。除了char成员之外,我正在返回错误。我对C相当陌生,所以我感谢你的帮助 来自csv文件“订单”的数据: 我的结构:将csv文件中的数据读取到结构中,并返回错误,c,csv,struct,C,Csv,Struct,我正在尝试将csv文件中的数据读取到结构中。结构包含int、char和float成员。除了char成员之外,我正在返回错误。我对C相当陌生,所以我感谢你的帮助 来自csv文件“订单”的数据: 我的结构: typedef struct { int position; char name[20]; float price; int counter; }drink; void init(drink *pt) { FILE *fp;
typedef struct {
int position;
char name[20];
float price;
int counter;
}drink;
void init(drink *pt)
{
FILE *fp;
char buf[50];
int i = 0, j;
fp=fopen("Order", "r");
while( fgets(buf,sizeof(buf),fp) != NULL)
{
strcpy(pt[i].position, strtok(buf,","));
strcpy(pt[i].name, strtok(NULL,","));
strcpy(pt[i].price, strtok(NULL,","));
strcpy(pt[i].counter, strtok(NULL,","));
++i;
}
}
int main()
{
int number = NR;
int d=0;
drink bar[number];
drink *pt = &bar[0];
welcome();
init(pt);
...
return 0;
}
strcpy()
将字符串复制到int
。而不是转换它
// strcpy(pt[i].position, strtok(buf,","));
char *endptr;
pt[i].position = strtol(strtok(buf,","), &endptr, 10);
// or
pt[i].position = atoi(strtok(buf,","));
...
pt[i].price = strtod(strtok(NULL,","), &endptr);
(注:省略各种错误检查)
您没有正确使用strcpy。 您应该仅将其用于字符缓冲区,而不是整数和浮点 阅读了解更多信息。
//要将字符缓冲区中的整数提取为int值,请使用atoi()而不是strcpy
// to extract a integer from a char buffer into a int value, use atoi() not strcpy
// to extract a float from a char buffer into a float value, use atof(), not strcpy
// the last field in a line probably does not have a trailing ','
// and the last field should already be '\0' terminated by the fgets
// so the code should use something else to get a pointer to the last field
// the calls to strtok() should be setting a char* field from the returned value
// then
// 1) that value can be checked for NULL
// 2) getting a pointer to the last field would be
// returnedValue+=2;
// (the 2 to skip over the intervening ' ' after the converted comma
// all the copying/converting of the fields need to advance the
// returnedValue by 1 to skip over the leading ' ',
// except the first field, which has no leading ' '
// the #define for 'NR' should be used in the function so as to
// not overflow the available number of input fields
// for most of the break; statements, you may want to add a printf
// so the user knows what happened
// suggest:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NR (20)
#define MAX_NAME_LEN (20)
typedef struct
{
int position;
char name[MAX_NAME_LEN];
float price;
int counter;
} drink;
void init(drink *pt)
{
char buf[50];
int i = 0; // loop counter
//int j = 0; // comment out or compiler will raise a warning about unused variable
char * returnFromStrtok = NULL;
FILE *fp = NULL;
if( NULL == (fp=fopen("Order", "r")) )
{ // then, fopen failed
perror( "fopen failed for: Order" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
for( i = 0; i<NR; i++)
{
if( NULL == fgets(buf,sizeof(buf),fp) ) break;
returnFromStrtok = strtok(buf, ",");
if( NULL == returnFromStrtok ) break;
pt[i].position = atoi(returnFromStrtok);
returnFromStrtok = strtok(NULL, ",");
if( NULL == returnFromStrtok ) break;
// step past leading ' '
returnFromStrtok++;
if( MAX_NAME_LEN <= strlen( returnFromStrtok ) )
{ // bad field, too long
memset( pt[i].name, '*', MAX_NAME_LEN ); // indicate invalid field
}
else
{
strcpy(pt[i].name, returnFromStrtok );
}
returnFromStrtok = strtok(NULL, ",");
if( NULL == returnFromStrtok ) break;
// step past leading ' '
returnFromStrtok++;
pt[i].price = atof(returnFromStrtok);
// +2 steps by '\0' and ','
returnFromStrtok += strlen(returnFromStrtok)+2;
pt[i].counter = atoi(returnFromStrtok);
} // end for
} // end function: init
//要将浮点从字符缓冲区提取为浮点值,请使用atof(),而不是strcpy
//行中的最后一个字段可能没有尾随“,”
//最后一个字段应该已经由fgets以“\0”结尾
//因此,代码应该使用其他方法来获取指向最后一个字段的指针
//对strtok()的调用应根据返回值设置char*字段
//然后
//1)可以检查该值是否为空
//2)获取指向最后一个字段的指针将是
//返回值+=2;
//(2在转换的逗号后跳过中间的“”
//所有字段的复制/转换都需要提前
//按1返回的值跳过前导的“”,
//除第一个字段外,该字段没有前导“”
//函数中应使用#define for'NR',以便
//不溢出可用的输入字段数
//对于大多数break;语句,您可能需要添加printf
//所以用户知道发生了什么
//建议:
#包括
#包括
#包括
#定义NR(20)
#定义最大名称长度(20)
类型定义结构
{
内部位置;
字符名[MAX_name_LEN];
浮动价格;
整数计数器;
}饮酒;
无效初始(饮料*pt)
{
char-buf[50];
int i=0;//循环计数器
//int j=0;//注释掉或编译器将发出有关未使用变量的警告
char*returnFromStrtok=NULL;
FILE*fp=NULL;
如果(NULL==(fp=fopen(“订单”,“r”))
{//然后,fopen失败了
perror(“fopen因订单失败”);
退出(退出失败);
}
//否则,fopen成功了
对于(i=0;iYou还应将bar数组的长度传递给init(),以防止其溢出数组。更好的是,应动态分配该数组,使其没有固定限制。需要检查调用strtok()返回的值,以确保操作成功(它可能不在一行的最后一个字段上,因为该字段没有以“,”结尾,建议将memset(pt[i].name,“*”,MAX_name_LEN);
更改为其他字段,以确保pt[i].name
以空字符结尾。
// to extract a integer from a char buffer into a int value, use atoi() not strcpy
// to extract a float from a char buffer into a float value, use atof(), not strcpy
// the last field in a line probably does not have a trailing ','
// and the last field should already be '\0' terminated by the fgets
// so the code should use something else to get a pointer to the last field
// the calls to strtok() should be setting a char* field from the returned value
// then
// 1) that value can be checked for NULL
// 2) getting a pointer to the last field would be
// returnedValue+=2;
// (the 2 to skip over the intervening ' ' after the converted comma
// all the copying/converting of the fields need to advance the
// returnedValue by 1 to skip over the leading ' ',
// except the first field, which has no leading ' '
// the #define for 'NR' should be used in the function so as to
// not overflow the available number of input fields
// for most of the break; statements, you may want to add a printf
// so the user knows what happened
// suggest:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NR (20)
#define MAX_NAME_LEN (20)
typedef struct
{
int position;
char name[MAX_NAME_LEN];
float price;
int counter;
} drink;
void init(drink *pt)
{
char buf[50];
int i = 0; // loop counter
//int j = 0; // comment out or compiler will raise a warning about unused variable
char * returnFromStrtok = NULL;
FILE *fp = NULL;
if( NULL == (fp=fopen("Order", "r")) )
{ // then, fopen failed
perror( "fopen failed for: Order" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
for( i = 0; i<NR; i++)
{
if( NULL == fgets(buf,sizeof(buf),fp) ) break;
returnFromStrtok = strtok(buf, ",");
if( NULL == returnFromStrtok ) break;
pt[i].position = atoi(returnFromStrtok);
returnFromStrtok = strtok(NULL, ",");
if( NULL == returnFromStrtok ) break;
// step past leading ' '
returnFromStrtok++;
if( MAX_NAME_LEN <= strlen( returnFromStrtok ) )
{ // bad field, too long
memset( pt[i].name, '*', MAX_NAME_LEN ); // indicate invalid field
}
else
{
strcpy(pt[i].name, returnFromStrtok );
}
returnFromStrtok = strtok(NULL, ",");
if( NULL == returnFromStrtok ) break;
// step past leading ' '
returnFromStrtok++;
pt[i].price = atof(returnFromStrtok);
// +2 steps by '\0' and ','
returnFromStrtok += strlen(returnFromStrtok)+2;
pt[i].counter = atoi(returnFromStrtok);
} // end for
} // end function: init