Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.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_Csv_Struct - Fatal编程技术网

将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;

我正在尝试将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;
 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