我有這樣的示例輸入檔案
第1344章 第
1344章 第1344章
首先,姓氏和姓氏用制表符分隔。但是,一個人可能有兩個名字。在這種情況下,名稱用空格分隔。
我正在嘗試從輸入檔案中讀取并將它們存盤在相關變數中。
這是我的代碼,當一個人只有一個名字時成功讀取。
fscanf(fp, "%d\t%s\t%s\t%d", &id, firstname, surname, &roomno)
問題是有沒有辦法讀取可能包含兩個名字的輸入檔案。
提前致謝。
uj5u.com熱心網友回復:
您可以使用說明%[符讀取字串中的空格:
fscanf(fp, "%d\t%[^\t]\t%[^\t]\t%d", &id, firstname, surname, &roomno)
uj5u.com熱心網友回復:
閱讀該行,fgets()然后將其保存為string。
然后決議字串。保存到足夠大小的緩沖區中。
掃描"\t", 掃描任意數量的空白 - 零個或更多。使用TABFMT下方掃描 1 個制表符。
一路上的測驗結果。
此代碼用于" %n"查看決議到達該點,僅此而已。
#define LINE_N 100
char line[LINE_N];
int id,
char firstname[LINE_N];
char surname[LINE_N];
int roomno;
if (fgets(line, sizeof line, fp)) {
int n = 0;
#define TABFMT "%*1[\t]"
#define NAMEFMT "%[^\t]"
sscanf(line, "%d" TABFMT NAMEFMT TABFMT NAMEFMT TABFMT "%d %n",
&id, firstname, surname, &roomno, &n);
if (n == 0 || line[n]) {
fprintf(stderr, "Failed to parse <%s>\n", line);
} else {
printf("Success: %d <%s> <%s> %d\n", id, firstname, surname, roomno);
}
}
如果姓氏或名字為空,則此代碼將其視為錯誤。
另一種方法是將行讀入字串,然后使用 strcspn(),strchr()或者strtok()查找要決議為 4 個子字串的選項卡。
OP 遺漏的更大問題是如何處理格式錯誤的輸入?錯誤處理通常被“輸入格式正確”所忽視,但在現實生活中,錯誤的輸入確實會發生,這也是黑客尋找的破解。防御性編碼采取步驟來驗證輸入。學究式的代碼根本不會使用*scanf(),而是fgets(), strcspn(), strspn(), strchr(), strtol()測驗、測驗、測驗。這個答案是一個中間的測驗作業。
uj5u.com熱心網友回復:
上述問題的答案是合理的,但問題是錯誤的。
這里的最終目標是讀取人名。人名有很多種——并非總是如此first, [middle,] last。這種假設是設計上的錯誤。
這是一個很多很多次重復的錯誤。最好不要重復。
最簡單的解決方案是重新排序資料欄位,并且不對名稱的結構做任何假設。所以輸入資料變成:
1344 1 Muhammad Ayyubi
1344 1 Muhammad Ali Ayyubi
掃描代碼然后可以提取前兩個數字欄位,并使用該行的其余部分作為名稱(不對結構做任何假設)。
更一般地說,如果您確實需要掃描帶有嵌入空格的欄位,請記住 ASCII 字符表中的 32 個“控制”字符,其中約 24 個沒有指定語意(當前使用)。您可以將結構添加到文本檔案中,例如使用 (from man ascii:
034 28 1C FS (file separator)
035 29 1D GS (group separator)
036 30 1E RS (record separator)
037 31 1F US (unit separator)
幾乎沒有允許文本欄位使用這些字符的情況。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/443800.html
上一篇:在DLL中動態選擇字串中的字串列
下一篇:資料框:如何洗掉字串中的點
