首页 文章

将数据从csv文件读入struct,得到错误

提问于
浏览
0

我正在尝试将csv文件中的数据读入结构中 . 该结构包含int,char和float成员 . 我收到错误,除了char成员 . 我对C很新,所以感谢你的帮助!

来自csv文件“订单”的数据:

0, cafe, 3.90, 0
0, espresso, 3.50, 0
...

我的结构:

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

3 回答

  • 0

    你没有使用strcpy正确 . 您应该只将它与char缓冲区一起使用,而不是与整数和浮点数一起使用 .

    有关它的更多信息,请阅读man strcpy .

  • 1
    • 错误的副本 .

    不要使用 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);
    

    (注意:省略了各种错误检查)

    • 启用所有编译器警告 . 这将节省您的时间,因为您的编译器应该 grab 它 .

    • 如果您收到错误,编译时间或运行时间,请发布错误而不是将错误描述为"getting errors back" .

  • 0
    // 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
    

相关问题