2017-09-02 120 views
-2

日安分離字符串和整數,使用分隔符

所以目前我有這個文件,包含:實際文件是這樣

1,name A. lname2,Das F. Esd3,Frsas A. Casdfre4,Rsadna P. Tsdaas5,Asadla C. Toasdtino6,Aasdel P. Gasdla7,Masda Isable A. Milasdroso8,Niasdkie T. Niasdemus9,Evasdn A. Vasdueva10,Geasdlyn C. Iasdncio11,Aasdr Leasdma12,Neasdio A. Maasdbale 

我有麻煩做輸出,這裏是我當前的代碼

printf("\nID\tName\n");  
while(fscanf(load, "%[^,],%[^1-9]", faculty[counter].id, faculty[counter].name)!=EOF) { 
    printf("%s\t%s", faculty[counter].id, faculty[counter].name); 

output
和輸出是這樣的:

ID Name  
1 asdasd  
2 asdas 
3 asdsad4  othername  
5 asdsad 
6 asdasda  
7 sdfsdf  
8 sadsad 
9 asdsad  
10 asdas  
11 asdsad12 asdas  
4,12 has invalid position. 

輸出應該是人氣指數:

1 ID Name  
1 asdasd  
2 asdas 
3 asdsad  
4 othername  
5 asdsad 
6 asdasda  
7 sdfsdf  
8 sadsad 
9 asdsad  
10 asdas  
11 asdsad  
12 asdas  

可能是什麼問題呢?這是我第一次使用這種分隔符,你能解釋一下這個問題嗎?謝謝!

+2

請對代碼塊,輸出和文件內容使用適當的格式。 @Someprogrammerdude試圖修復它,但你的編輯改變了它。 Eimantas應用的最新修補程序。 – Myst

+0

代碼固定,對不起 –

+0

你在'fscanf'中使用正則表達式;這是不正確的,它只能理解格式字符串。 –

回答

0

更改格式如下:

printf("\nID\tName\n");  
while (fscanf(load, " %[0-9], %[^0-9]", faculty[counter].id, faculty[counter].name) == 2) { 
    printf("%s\t%s\n", faculty[counter].id, faculty[counter].name); 
    ... 
    counter++; 
} 

請注意,您也應該通過的最大字符數存儲到目標陣列以避免潛在的緩衝區溢出。

但請注意,發佈在問題中的示例輸出與代碼片段不一致:您不會輸出格式爲printf的換行符,並確認數據文件中沒有換行符,輸出中的換行符來自哪裏從?

你可以製作一個帶有假名稱的測試文件來顯示問題嗎?還發布失敗的完整代碼。結構定義也很重要。沒有精確的數據和代碼就很難設置診斷。

+0

只有1個輸出與此一起顯示 –

+0

您顯示的輸出與您發佈的文件內容不一致。數字後面總是有逗號?該文件是否包含換行符? – chqrlie

+0

是的,就是這樣,在數字後面有一個逗號,但在姓氏後面沒有逗號,沒有換行符 1,fistname A. lastname2,firstname F. lastname 我剛添加了一些隨機字符,因爲它包含真實姓名,對不起, –

0

這是一種情況,其中有fscanf閱讀單獨可以工作,但通過閱讀完整的行一次,然後解析符合或者sscanf或者乾脆走路一對字符指針的上下行採摘缺乏穩健性就可以實現出idname對。

要在已發佈的輸入線路上使用fscanf,您可以使用格式說明的"%d,%[^0-9]"在重複調用fscanf。 (如果名稱長於數組大小,則應提供字段寬度修飾符以防止發生溢出)。例如,你可以這樣做以下操作以獲取每個idname對(這只是輸出在下面的例子):

#include <stdio.h> 

enum { MAXNM = 64 }; /* constant for max characters in name */ 

int main (int argc, char **argv) { 

    int id; 
    char name[MAXNM] = ""; 
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin; 

    if (!fp) { /* validate file open for reading */ 
     fprintf (stderr, "error: file open failed '%s'.\n", argv[1]); 
     return 1; 
    } 

    /* read each 'id,name' pair (name cannot include digits) */ 
    while (fscanf (fp, "%d,%63[^0-9]", &id, name) == 2) 
      printf ("%3d %s\n", id, name); 

    if (fp != stdin) fclose (fp);  /* close file if not stdin */ 

    return 0; 
} 

示例使用/輸出

$ ./bin/rd_num_name <dat/num_names.txt 
    1 name A. lname 
    2 Das F. Esd 
    3 Frsas A. Casdfre 
    4 Rsadna P. Tsdaas 
    5 Asadla C. Toasdtino 
    6 Aasdel P. Gasdla 
    7 Masda Isable A. Milasdroso 
    8 Niasdkie T. Niasdemus 
    9 Evasdn A. Vasdueva 
10 Geasdlyn C. Iasdncio 
11 Aasdr Leasdma 
12 Neasdio A. Maasdbale 

如果你想使用面向行的輸入與fgetsgetline讀取整個行,然後分析每個idname從緩衝器保持整行,則可以做如下的事情。讀取整行,然後解析的好處是,它將讀取與解析分離開來,從而可以驗證兩者。此外,您的閱讀不受匹配失敗輸入格式的輕微變化。

在這裏,用sscanf以及利用所述%n格式說明以確定由每一次調用sscanf消耗的字符數,可以步行指針向下行挑選出idname雙,例如

#include <stdio.h> 

enum { MAXNM = 64, MAXLN = 512 }; /* max name & line constants */ 

int main (int argc, char **argv) { 

    int id; 
    char name[MAXNM] = "", 
     line[MAXLN] = "", 
     *p = line;   /* pointer to line to walk string */ 
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin; 

    if (!fp) { /* validate file open for reading */ 
     fprintf (stderr, "error: file open failed '%s'.\n", argv[1]); 
     return 1; 
    } 

    while (fgets (line, sizeof line, fp)) /* read each line/validate */ 
    { 
     int offset = 0;      /* number of char processed */ 
     while (sscanf (p, "%d,%63[^0-9]%n", &id, name, &offset) == 2) { 
      printf ("%3d %s\n", id, name); 
      p += offset;     /* advance to next id,name */ 
     } 
    } 

    if (fp != stdin) fclose (fp);  /* close file if not stdin */ 

    return 0; 
} 

注:輸出是一樣的。