簡體   English   中英

使用C計算ASCII文件中的行數

[英]Count lines in ASCII file using C

我想計算ASCII文本文件中的行數。 我認為最好的方法是計算文件中的換行符:

for (int c = fgetc(fp); c != EOF; c = fgetc(fp)) {  /* Count word line endings. */
    if (c == '\n') ++lines;
}

但是,我不確定這是否會占據MS Windows和Linux上的最后一行。 也就是說,如果我的文本文件如下所示完成,沒有明確的換行符,那么還是有一個編碼在那里,或者我應該添加額外的++lines; 在for循環之后?

cat
dog

那么什么樣,如果沒有在文件的結尾明確的新行? 或者我只是需要通過跟蹤先前讀取的值來測試這種情況?

如果沒有換行符,則不會生成換行符。 C告訴你究竟是什么。

文本文件始終以換行符結束。 沒有規范的方法來處理沒有的文件。

以下是一些工具在最后一次換行后選擇處理字符的方式:

  • wc不算作一條線(所以你有優先權)
  • Vim將文件標記為[noeol] ,並保存文件而不使用尾隨換行符
  • GNU sed將文件視為具有最后一行換行符
  • shread出錯但仍然返回數據

由於行為幾乎未定義,您可以做任何方便或有用的事情。

首先,在最后一行的末尾不會有任何隱式編碼的換行符。 新行的唯一方法是生成該文件的軟件或人員將其放在那里。 然而,把它放在那里通常被認為是良好的做法。

您應該報告為行數的最終答案取決於您需要遵循的軟件或將使用此行數的人員的約定,以及您可能對輸入源的行為也可以假設的內容。

大多數命令行工具將使用換行符終止其輸出。 在這種情況下,明智的答案可能是將換行符的數量報告為實際行數。

另一方面,當文本編輯器顯示文件時,您將看到邊距中的行編號(如果支持)包含最后一行的編號,無論它是否為空。 這部分是為了告訴用戶那里有一個空白行,但是如果你想計算邊距中顯示的行數,那么它就是一個加上文件中換行符的數量。 一些編碼員通常不會使用換行符來終止他們的最后一行(有時是由於邋iness),因此在這種情況下,這種慣例實際上是正確的答案。

我不確定任何其他慣例是否有意義。 例如,如果您選擇不計算最后一行,除非它是非空的,那么什么算作非空? 換行后的文件? 如果該行上有空格怎么辦? 如果文件末尾有幾個空行怎么辦?

如果你打算使用這種方法,你可以隨時為你所在線上的字母數量保留一個單獨的計數器。 如果最后的計數大於1,那么你就知道最后一行的東西沒有被計算在內。

int letters = 0

for (int c = fgetc(fp); c != EOF; c = fgetc(fp)) {  /* Count word line endings. */
    letters++; // Increase count on character

    if (c == '\n')
    {
        ++words;
        letters = 0; // Set back to 0 after new line
    }
}

if (letters > 0)
{
    ++words;
}

您的擔憂是真實的,文件中的最后一行可能缺少行標記的最后一行。 行尾標記在Linux中是單個'\\n' ,在Windows中是CR LF對,C運行時自動轉換為'\\n'

您可以簡化代碼並處理最后一行錯過換行符的特殊情況:

int c, last = '\n', lines = 0;

while ((c = getc(fp)) != EOF) {  /* Count word line endings. */
    if (c == '\n')
        lines += 1;
    last = c;
}
if (last != '\n')
    lines += 1;

由於您關心速度,使用getc而不是fgetc將有助於在平台上將其定義為直接處理流結構的宏並調用函數僅重新填充緩沖區,每個BUFSIZ字符左右,除非流是無緩沖的。

這個怎么樣:

為自己創建一個標志,以跟蹤在c=='\\n'時重置的\\n后面的任何非\\n字符。 EOF ,檢查標志是否為真,如果是則增加。

bool more_chars = false;
for (int c = fgetc(fp); c != EOF; c = fgetc(fp)) {  /* Count word line endings. */
            if (c == '\n') {
              more_chars = false;
              ++words;
            } else more_chars = true;
 }
 if(more_chars) words++;

Windows和UNIX / Linux樣式換行符在這里沒有區別。 在任一系統上,文本文件在最后一行的末尾可能有也可能沒有換行符。

如果你總是加1,行數,這有效地計算在文件末尾的空行,當在最后一個換行符(即文件"foo\\n"將計為有兩行: "foo""" )。 這可能是一個完全合理的解決方案,具體取決於您要如何定義一條線。

“行”的另一個定義是它總是以換行符結束,即文件"foo\\nbar"只有一行( "foo" )。 這個定義由wc

當然,您可以跟蹤換行符是否是文件中的最后一個字符,並且只有在不是時才向計數添加1。 然后一個“行”將被定義為以換行結尾或在文件末尾非空,這對我來說聽起來相當復雜。

暫無
暫無

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

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