[英]Reading from Text files in C
確實是一個小問題。 最好讀取一個包含X個單詞的文本文件,並將每個單詞一個接一個地添加到鏈接列表中。 即青蛙是老。
因此,The,Frog,Is和Old將分別放入一個ListNode中,所有這些都是從文件中讀取的。
真的想知道與fscanf一起使用的最佳功能,如果fscanf甚至是最佳選擇。 所有建議都很棒!
干杯。
編輯:我的查詢是真的,如果我想解析一個大的文本文件,是否最好將一個單詞fscanf逐個地放入數組,添加到列表,自由數組,然后重復? 還是有更有效的方法
“%s”轉換說明符將匹配非空格字符。
#define QUOTE(s) #s
#define STR(s) QUOTE(s)
#ifndef BUFSIZE
# define BUFSIZE 255
#endif
char buf[BUFSIZE+1];
while (fscanf(fin, "%" STR(BUFSIZE) "s", buf)) {
/* buf holds next word. Todo:
+ allocate space for word
+ copy word to newly allocated space
+ add to linked list
*/
}
另外, strtok
可用於使用指定的一組字符(作為字符數組)將字符串標記化(分解)為子字符串。 您的系統可能還具有strsep
,旨在取代strtok
。 strtok
和strsep
修改您傳入的數組,因此請注意,這不會導致訪問數據的代碼其他部分出現問題。 strsep
不是線程安全的; 如果您有多個線程訪問要解析的字符串,請使用strsep
或strtok_r
。
#ifndef BUFSIZE
# define BUFSIZE 256
#endif
const char separators[] = "\t\n\v\r\f !\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~";
char buf[BUFSIZE], *line, *word, *rest;
while (fgets(buf, BUFSIZE+1, fin)) {
rest = line = buf;
while ((word = strtok_r(line, separators, &rest))) {
/* Todo:
+ allocate space for word
+ copy word to newly allocated space
+ add to linked list
*/
line=rest;
}
}
由於第二個示例一次從文件中讀取一行以供strtok_r
處理,因此如果文件中的任何一行的長度超過BUFSIZE-1 個字符,並且一行中的BUFSIZE-1 st和BUFSIZE th字符均為字母,則第二個示例將單詞分成兩部分。 一種解決方案是創建一個緩沖的字符串流,以便在到達緩沖區的末尾時,緩沖區中剩余的所有內容都移到最前面,而緩沖區的其余部分則充滿了文件中的更多數據(只是請注意字長比緩沖區長;在生產代碼中,這是一個潛在的安全漏洞,可能導致拒絕服務攻擊。
上述所有功能的問題是它們不能處理輸入中的空字符。 如果您想解析可能包含空字符的數據,則需要使用非標准函數,其中包括編寫自己的函數。
至於效率,您使用的任何算法都需要從文件中讀取(復雜度為O(n),並且需要I / O,從而降低程序速度)並分配內存來存儲字。 無論您使用fscanf
, strtok
還是其他方法,時間和空間的復雜性變化都不大。 關於唯一可能的事情是分配了多少個中間緩沖區。 找到最有效的實施方案的最佳選擇是嘗試一對夫婦並進行介紹。
除非您擁有“效率不夠的方法”,否則您不應該在尋找“更有效的方法”。
但是類似strtok
東西可能不需要大量malloc
可以滿足您的需求。 它使您可以將琴弦切成適當的位置 。 (請謹慎使用!)
如果您追求高速,請在現代台式計算機上...您可以使用多線程。
這個想法是等待I / O時進程不會休眠。 如果您有很多CPU內核,則要提高速度,就是將文件切成大塊,然后一個內核處理一個塊。 復雜代碼和錯誤的機會很多,但是,速度並不便宜...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.