簡體   English   中英

從C中的文本文件讀取

[英]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 strtokstrsep修改您傳入的數組,因此請注意,這不會導致訪問數據的代碼其他部分出現問題。 strsep不是線程安全的; 如果您有多個線程訪問要解析的字符串,請使用strsepstrtok_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,從而降低程序速度)並分配內存來存儲字。 無論您使用fscanfstrtok還是其他方法,時間和空間的復雜性變化都不大。 關於唯一可能的事情是分配了多少個中間緩沖區。 找到最有效的實施方案的最佳選擇是嘗試一對夫婦並進行介紹。

除非您擁有“效率不夠的方法”,否則您不應該在尋找“更有效的方法”。

但是類似strtok東西可能不需要大量malloc可以滿足您的需求。 它使您可以將琴弦切成適當的位置 (請謹慎使用!)

如果您追求高速,請在現代台式計算機上...您可以使用多線程。

  • 一個線程填充字符緩沖區(例如4Ko),並且僅執行此操作
  • 一個線程讀取緩沖區,解析單詞並將其添加到列表中
  • 如果您不需要整個列表,則一個線程可以執行您在列表上所做的任何操作

這個想法是等待I / O時進程不會休眠。 如果您有很多CPU內核,則要提高速度,就是將文件切成大塊,然后一個內核處理一個塊。 復雜代碼和錯誤的機會很多,但是,速度並不便宜...

暫無
暫無

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

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