7

このサイトには、さまざまな方法を使用してテキスト ファイルの行を印刷する方法を説明する方法がたくさんあります。

それらはすべて、特定の例に合わせて調整されているようです。

テキストファイルの各行を画面に出力する、最も明確最も簡潔最も簡単な方法があれば素晴らしいと思います。できれば、各行が何をするかについての詳細な説明が必要です。

簡潔さと明確さのためのポイント。

4

4 に答える 4

9
#include <stdio.h>

static void cat(FILE *fp)
{
    char   buffer[4096];
    size_t nbytes;
    while ((nbytes = fread(buffer, sizeof(char), sizeof(buffer), fp)) != 0)
         fwrite(buffer, sizeof(char), nbytes, stdout);
}

int main(int argc, char **argv)
{
    FILE *fp;
    const char *file;
    while ((file = *++argv) != 0)
    {
        if ((fp = fopen(file, "r")) != 0)
        {
            cat(fp);
            fclose(fp);
        }
    }
    return(0);
}

このcat()機能は厳密には必要ではありませんが、むしろ使用したいと思います。メイン プログラムは、各コマンド ライン引数を順に処理し、指定されたファイルを開きます。成功した場合は、cat()関数を呼び出して内容を出力します。への呼び出しでfopen()は が指定されていない"rb"ため、テキスト ファイルとして開かれます。ファイルが開かれていない場合、このコードは問題を黙って無視します。ファイルが指定されていない場合、何も印刷されません。

このcat()関数は、一度に 4096 バイトまでのテキスト ブロックを単純に読み取り、標準出力 (「画面」) に書き込みます。読むものがなくなったら停止します。

ファイルが指定されていないときに標準入力を読み取るようにコードを拡張する場合は、次を使用できます。

if (argc == 1)
    cat(stdin);
else
{
    ...while loop as now...
}

これは、関数が示されているように記述されている理由の 1 つですcat()

このコードは、改行、またはあらゆる種類の行に直接注意を払いません。一度に1行ずつ正式に処理したい場合は、いくつかのことを行うことができます:

static void cat(FILE *fp)
{
    char buffer[4096];
    while (fgets(buffer, sizeof(buffer), fp) != 0)
         fputs(buffer, stdout);
}

これにより、一度に 1 行ずつ読み取りと書き込みが行われます。いずれかの行が 4095 バイトを超える場合、2 回以上の操作でその行を読み取り、同じ回数の操作で書き込みます。これは、使用しているバージョンと使用fread()してfwrite()いない方法でテキスト ファイルを想定していることに注意してください。POSIX システムでは、fread()とを使用したバージョンは、データにfwrite()ヌル バイト ( ) を含む任意のバイナリ ファイルを処理しますが、とを使用したバージョンは処理しません。これまでのところ両方のバージョンは、プラットフォーム固有の拡張機能を使用していないため、厳密に標準 C (標準の任意のバージョン) です。それらはコードと同じくらい移植性があります。'\0'fgets()fputs()

別の方法として、POSIX 2008getline()関数がある場合はそれを使用できますが、それも必要です#include <stdlib.h>(割り当てられたメモリを解放する必要があるため)。

static void cat(FILE *fp)
{
    char *buffer = 0;
    size_t buflen = 0;
    while (getline(&buffer, &buflen, fp) != -1)
         fputs(buffer, stdout);
    free(buffer);
}

このバージョンも、バイナリ データ (null バイトを含むデータ) を処理しません。もちろん、そうするためにアップグレードすることもできます:

static void cat(FILE *fp)
{
    char *buffer = 0;
    size_t buflen = 0;
    ssize_t nbytes;
    while ((nbytes = getline(&buffer, &buflen, fp)) != -1)
         fwrite(buffer, sizeof(char), nbytes, stdout);
    free(buffer);
}

このgetline()関数は、読み取ったバイト数を報告します (その後に null バイトがあります) が、このfwrite()関数は、任意のバイトのストリームを取り、それらすべてを指定されたストリームに書き込む唯一の関数です。

于 2012-12-28T00:09:38.917 に答える
2

さて、これが私が最終的に作った非常に短い解決策です。それ以外の場合は提案されていたはずの根本的な問題があると思いますが、ここに投稿して、誰かがそれを引き裂くことを願っています:

#include <stdio.h>
main()
{
    FILE *MyFile;
    int c;
    MyFile=fopen("C:\YourFile.txt","r");
    c = fgetc(MyFile);
    while (c!=EOF)
    {
        printf("%c",c);
        c = fgetc(MyFile);
    }
}
于 2013-01-02T23:53:14.280 に答える
1

@Dlinet、あなたはプログラムを編成する方法についていくつかの有用なレッスンを学ぼうとしています。すでに本当に優れた答えがあるので、私はコードを投稿しません。私はおそらくそれを改善することはできません。しかし、私はあなたに本を推薦したいと思います。

この本は、Pascalではソフトウェアツールと呼ばれています。言語はCではなくPascalですが、本を読むためにこれは深刻な困難を引き起こしません。彼らは、この例(UNIXでは呼ばれるcat)のような単純なツールの実装から始めて、より高度なものに移ります。彼らはこの種のプログラムをどのように編成するかについて素晴らしいレッスンを教えるだけでなく、言語デザインの問題もカバーしています。(Pascalには本当に厄介な問題があり、Cを知っていれば、Cにはそれらの問題がないことに気付くでしょう。)

この本は現在絶版ですが、コードの書き方を学んでいたときに非常に価値があることがわかりました。いわゆる「左隅の設計」の方法論は、今日まで私に役立ちます。

アマゾンなどで中古品を探すことをお勧めします。Amazonは、0.02ドルから4ドルの送料でコピーを使用しています。

http://www.amazon.com/Software-Tools-Pascal-Brian-Kernighan/dp/0201103427

この本のプログラムを研究し、Cで実装することは教育的な演習になります。どのLinuxシステムにも、これらのプログラムのより強力で完全にデバッグされたバージョンがすでにありますが、これを実行するのに時間の無駄はありません。このようなものを予約して書く方法を学びましょう。

または、FreePascalをコンピューターにインストールし、それを使用して本からプログラムを実行することもできます。

幸運を祈ります。いつもソフトウェア開発を楽しんでください。

于 2012-12-28T01:04:03.983 に答える
0

事前に作成したものが必要な場合はcat、POSIX システムにあります。

自分で書きたい場合の基本的なレイアウトは次のとおりです。

  1. ファイル名、権限、およびパスが有効であることを確認してください
  2. ループ内で改行区切りまで読み取る (Unix では \n、Windows/DOS では \r\n)
  3. エラーがないか確認してください。もしそうなら、エラーを出力して中止します。
  4. 行を画面に出力します。
  5. 繰り返す

つまり、具体的な方法はありません。読んで、書いて、繰り返すだけです。いくつかのエラー チェックを行うと、再び cat が発生します。

于 2012-12-28T00:08:07.077 に答える