2017-03-20 8 views
0

コードはWindows上のコンパイラでは正常に動作しますが、Linuxでは正常に動作しません。 Linuxでは、2倍以上の行と負数の列を返します。 Win8.1 x86_64、Linux 16.04 64ビット。私はWindows(MINGW)上にGCC v5.3を持っていますが、LinuxではGCC v5.4.0を持っています。印刷用コードファイル内の行数と列数。 Windows Mingw gcc環境では動作しますが、Linuxでは動作しないのはなぜですか?

#include <stdio.h> 

// count Lines of a file 
size_t countLinesOfFile(char *fileName) 
{ 
    FILE *fp = fopen(fileName, "r"); 
    char ch; 
    size_t lines = 0; 
    do { 
     ch = fgetc(fp); 
     if(ch == '\n' || ch == '\r') 
      lines++; 
    } while (ch != EOF); 
    //while (!feof(fp)) 

    // if last line doesn't end with a new line character! augment No of lines 
    if(ch != '\n' || ch != '\r') 
     lines++; 

    fclose(fp); 
    return lines; 
} 

// assuming that the file has equal number of columns for all its lines 
// (or just 1 line) 
size_t countColumnsOfFile(char *fileName) 
{ 
    FILE *fp = fopen(fileName, "r"); 
    char ch; 
    size_t columns = 0; 
    while ((ch != '\n' || ch != '\r') && ch != EOF) { // we only want to count one line so which ever comes first 
     ch = fgetc(fp); 
     columns++; 
    } 
    columns--; 
    //feof(fp) = found end of file, returns non zero(true) if found 

    fclose(fp); 
    return columns; 
} 
+4

'char ch'は' int ch'である必要があります。失敗する可能性のある呼び出しのエラーチェックが必要です。 'fopen'。 –

+5

Windowsで作成されたテキストファイルでLinuxが行う行は、それぞれの行が終わるたびに '\ r'と' \ n'を両方とも持ちますか? –

+2

'char ch'と' int ch'の違いは**重要です**](http://stackoverflow.com/questions/35356322/difference-between-int-and-char-in-getchar-fgetc- and putchar-fputc) –

答えて

0

とする必要があります。私はこの時と少し混乱していました。ここにコードは、プレーンでシンプルです。 MACでは機能しません("\n""\r"に置き換える必要があります)。

// count lines of a file 
size_t countLinesOfFile(char *fileName) 
{ 
    FILE *fp = fopen(fileName, "r"); 
    char ch; 
    size_t lines = 1; // every file starts from line #1 

    do { 
     ch = fgetc(fp); 
     if(ch == '\n') 
      lines++; 
    } while (ch != EOF); 
    //while (!feof(fp)) 

    fclose(fp); 
    return lines; 
} 

// assuming that the file has equal ammount of columns 
// calculate columns of a file (maximum ammount of columns in any given line) 
size_t countColumnsOfFile(char *fileName) 
{ 
    FILE *fp = fopen(fileName, "r"); 
    char ch; 
    size_t columns = 0; 

    while (ch != '\n' && ch != EOF) { 
     ch = fgetc(fp); 
     columns++; 
    } 
    // note that #(chars in the line) = #(columns) - 1 

    fclose(fp); 
    return columns; 
} 


int main() 
{ 
    printf("lines = %d\n", countLinesOfFile("file.txt")); 
    printf("columns = %d\n", countColumnsOfFile("file.txt")); 
} 
5

あなたは\r\nの両方を読んだときあなたはlinesをインクリメントしています。 Windowsでテキストファイルを作成すると、改行シーケンスとしてCRLFが使用されますが、C stdioライブラリでは、これらの文字を単一の\n文字に結合します(バイナリモードでファイルを開く場合を除く)。

UNIXは、改行文字としてLFを使用します。ファイルをWindowsからUnixにコピーすると、CRとLFのそれぞれが別の文字(\r\n)として読み込まれます。あなたのコードはそれぞれに対してlineをインクリメントするので、各行を2回カウントします。これはUnix上で作成したファイルでは起こりません。

だから、ちょうど\nを数える必要があります。テキストモード(デフォルト)でファイルを開く限り、これはあなたが見るべき唯一の改行文字です。 Cライブラリは、OSの改行シーケンスが何であっても、この文字に変換する必要があります。

ところで、このラインは2つの方法で間違っている:

// if last line doesn't end with a new line character! augment No of lines 
if(ch != '\n' || ch != '\r') 

まず、あなたは文字が\n\rないかどうかをテストしたい場合は、&&、ない||を使用する必要があります。 Why non-equality check of one variable against many values always returns true?

セカンドを参照してください、ときch == EOFループは終了し、それは常に\r\nと等しくなります。最後の行の終わりをテストしたい場合は、ch = fgetc(fp);の割り当てを繰り返す前に、各文字を別の変数に保存する必要があります。

列カウントコードには、リストに一致しない文字をテストする場合と同じ問題があります。それは、

while (ch != '\n' && ch != '\r' && ch != EOF) { // we only want to count one line so which ever comes first 
+0

それはそうではありません。私は実際には '\ n'のみを使用しました。その後、私は\ rを試してみると、違いはありますが、何も変わらないのかどうかは分かりません。それはうまくいかなかった。列番号は特にここでの問題です。 –

+0

列番号コードには 'if'文と同じ問題があります。 – Barmar

+0

@ RestlessC0bra行末を確実にするために、テキストファイルのダンプを見ましたか? –

関連する問題