2010-04-07 43 views
0

我不明白爲什麼atoi()對除第一個元素之外的每個項都有效。我有以下代碼來解析一個簡單的.csv文件:從文件中讀取時,atoi()僅在第一個元素上返回零。

void ioReadSampleDataUsers(SocialNetwork *social, char *file) { 
    FILE *fp = fopen(file, "r"); 

    if(!fp) { 
     perror("fopen"); 
     exit(EXIT_FAILURE); 
    } 

    char line[BUFSIZ], *word, *buffer, name[30], address[35]; 
    int ssn = 0, arg; 

    while(fgets(line, BUFSIZ, fp)) { 
     line[strlen(line) - 2] = '\0'; 

     buffer = line; 
     arg = 1; 

     do { 
      word = strsep(&buffer, ";"); 

      if(word) { 
       switch(arg) { 
        case 1: 
         printf("[%s] - (%d)\n", word, atoi(word)); 
         ssn = atoi(word); 
         break; 
        case 2: 
         strcpy(name, word); 
         break; 
        case 3: 
         strcpy(address, word); 
         break; 
       } 

       arg++; 
      } 
     } while(word); 

     userInsert(social, name, address, ssn); 
    } 

    fclose(fp); 
} 

而且該.csv示例文件是這樣的:

900011000;Jon Yang;3761 N. 14th St 
900011001;Eugene Huang;2243 W St. 
900011002;Ruben Torres;5844 Linden Land 
900011003;Christy Zhu;1825 Village Pl. 
900011004;Elizabeth Johnson;7553 Harness Circle 

但是,這是輸出:

[900011000] - (0) 
[900011001] - (900011001) 
[900011002] - (900011002) 
[900011003] - (900011003) 
[900011004] - (900011004) 

什麼我做錯了嗎?

+0

您還可以打印strlen(單詞)嗎? – 2010-04-07 16:43:08

+0

它爲第一個和第九個打印出'12'... – 2010-04-07 16:47:48

回答

5

我猜你的CSV文件是以UTF-8格式保存的,並且在開始時有一個BOM(byte order mark),令人迷惑atoi。您可以通過在十六進制編輯器中查看文件或查看word的前幾個字節來驗證此情況。

UTF-8的BOM是三個字節,值爲0xEF,0xBB和0xBF。

如果可能,請將文件另存爲ASCII。如果不是,請添加代碼以檢測並跳過這些字節。

+0

特別可能一旦你考慮到strlen()的結果。 – 2010-04-07 16:49:09

+0

只需將該文件保存爲ANSI,即可解決該問題。我不認爲輸入需要以UTF-8保存。 – 2010-04-07 16:53:52

+0

我想你是指utf-16。如果是utf8,那麼當限制字節值0-127時它將是ascii,並且不需要字節排序代碼。 – nategoose 2010-04-07 20:09:37

2

我的猜測是該文件以字節順序標記開頭。 atoi()將其視爲非數字,因此返回0.

if (line[0] == 0xEF && line[1] == 0xBB && line[2] == 0xBF) { 
    /* byte order mark is present, so skip it somehow */ 
} 
相關問題