簡體   English   中英

讀取csv文件到c結尾

[英]read csv file to its end in c

因此,我有這段代碼可以從csv文檔中讀取很多行。 我知道文檔最初有16行,這就是為什么我指定int noRows = 16; 在我的主要功能上。

void readBeer(int noRows) {
char *oneline, *token;
char oneproduct[256];
char delim[] = ",";
int x = 1;

FILE *fp; //open file
if ((fp = fopen("varor.csv", "r")) == NULL) //can the file be opened?
{
fprintf(stderr, "File varor.csv couldn't be opened\n"); //"couldn't open file"
exit(-1);
}

while(noRows != 0) 
{
    int countTok = 1;

    fgets(oneproduct, 256, fp); //get the first row
    oneproduct[strlen(oneproduct) - 1] = '\0'; // remove end-of-line character

    oneline = strdup(oneproduct); //duplicate oneproduct into oneline because strtok modifies the given string
    token = strtok(oneline, delim); //split oneline into tokens, tokens are separated by ","

    while (token != NULL) 
    {
        if(countTok == 1) beer[x].productNumber = atoi(token);
        else if(countTok == 2) strcpy(beer[x].name, token);
        else if(countTok == 3) beer[x].price = atof(token);
        else if(countTok == 4) beer[x].volume = atof(token);
        else if(countTok == 5) strcpy(beer[x].type, token);
        else if(countTok == 6) strcpy(beer[x].style, token);
        else if(countTok == 7) strcpy(beer[x].packaging, token);
        else if(countTok == 8) strcpy(beer[x].country, token);
        else if(countTok == 9) strcpy(beer[x].manufacturer, token);
        else if(countTok == 10) beer[x].alcohol = atof(token);
        else printf("kossan hoppade!"); //should never be seen in console
        token = strtok(NULL, delim);
        countTok++;
    }

    x++;
    noRows--;
    free(oneline); free(token);

}

fclose(fp);

}

我的問題是,如何在不知道文件有多少行的情況下讀取文件的末尾? 我正在考慮在文件中具有特定的單元格,只是為了保存控制台啟動和關閉之間的noRows

我嘗試使用char buffer[1000]; while(fgets(buffer, 1000, fp)) {} char buffer[1000]; while(fgets(buffer, 1000, fp)) {} ,然后它讀取前8行(不確定是否總是8)作為0,0,0,0,0,0,0,0,0,0 。

您的問題的答案是否只是測試fgets的返回值

for (;;)   // idiomatic C style for an infinite loop 
{
    int countTok = 1;

    if (NULL == fgets(oneproduct, 256, fp)) break; //get one row and exit loop on EOF
    ...

但是正如您在注釋中告訴您的那樣,您的代碼中還有許多其他問題:

  • 您將索引初始化為1,而C數組索引從0開始x=1; 應該是x=0; 由於相同的原因, countTok = 1; 沒錯,但是countTok = 0; 會更慣用C
  • 您可以使用fprintf(stderr, ...在打開文件時注意到錯誤。雖然沒有錯,但它並未指出錯誤原因perror可以...
  • 你刪除的最后一個字符oneproduct沒有controling它是一個換行符。 這個假設是錯誤的

    • 如果一行至少包含256個字符
    • 如果最后一行不以換行符結尾

    慣用的方法是使用strcspn

     oneproduct[strcspn(oneproduct, "\\n")] = '\\0'; // erase an optional end of line 
  • 您將oneproduct復制到oneline 同樣,這沒什么錯,但是這沒用,因為您永遠不會使用原始行
  • 一長串的else if是否可以用開關代替,但這主要是樣式問題
  • 您可以在循環結束時釋放token 因為它為NULL,所以它是一個空操作,但未分配它,因此不應釋放它。

如果使用的是fgets ,則可以測試調用的結果是否等於NULL fgets在錯誤或EOF (文件結束)時發出NULL信號。

char *fgets(char *line, int maxline, FILE *fp);

IE:

while (fgets(buffer, MAXLINE, fp) != NULL) {
    // Process line here.
}

您還可以逐個字符地處理整個文件,並測試(c == EOF) 有兩種方法可以做到這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM