-2

重複の可能性:
C でファイルの内容を取得する最も簡単な方法

この投稿fseekを見ましたが、まだ含まれていると感じていますftellなど。また、組み合わせを使用する他のいくつかの方法を見ましたが、ループ条件には適していないfeof+fgetcと彼らは言います。また、私が退屈だと思う行ごとにfeof使用して読むことを提案する人もいます。fgets

ファイルの内容全体を読み取るための他の短い方法はありますか?

PS: 短くすると、コード行を意味します。

4

2 に答える 2

2

使用するmmap()か、自分で実行してください。

エラーチェックを省略すると、おおまかに次のようになります。

int fd = open(filename, O_RDONLY);
struct stat sb;
fstat(fd, &sb);
char *contents = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);

これはファイルの読み取り専用コピーで、カーネルが選択したアドレスに割り当てられます。32 ビット システムを使用している場合は、2 GiB を超えるファイルについて心配する必要があるかもしれません。fstat()ファイルサイズを取得するなどの使用をポータブルに回避できるとは思いません。ファイルを拡張する場合は、POSIX 仕様に従って、ファイル サイズよりも大きなサイズを指定できます。

DIY の場合、最初の 3 行は同じです。次に、次を使用します。

char *contents = malloc(sb.st_size);
read(fd, contents, sb.st_size);

前述のように、これらの例ではすべてのエラー チェックが省略されています。本番対応のコードでリスクを冒さないでください。


mmap()私は、次のものを使用して見つけた、より本番環境に近いコードを探しに行きました。

static int sqs_mapfile(const char *file)
{
    int   fd;
    void *vp;
    struct stat sb;

    if (file == 0)
        return(SQS_NOSQSFILE);
    if ((fd = open(file, O_RDONLY, 0)) < 0)
        return(SQS_OPENFAIL);
    if (fstat(fd, &sb) != 0)
    {
        close(fd);
        return(SQS_STATFAIL);
    }
    vp = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    close(fd);
    if (vp == MAP_FAILED)
        return(SQS_MMAPFAIL);

「SQS_xyz」コードは、それが由来するプログラムに固有のものです (関数名と同様)。このコードはopen()、2 つの引数のバージョンで十分な 3 つの引数の呼び出しを使用します。

于 2012-04-19T19:36:30.513 に答える
1

実際に機能する可能性が最も高い最短の方法は、次の順序であると思います。

char *buffer;
size_t size;

fseek(your_file, 0, SEEK_END);
size = ftell(your_file);
rewind(your_file);
buffer = malloc(length);
fread(buffer, 1, length, your_file);

もちろん、必要なのは一度だけです。

char *read_file(FILE *file) { 
    char *buffer;
    size_t size;

    fseek(your_file, 0, SEEK_END);
    size = ftell(your_file);
    rewind(your_file);
    buffer = malloc(length);
    if (buffer) fread(buffer, 1, length, your_file);
    return buffer;
}

それはただです:char *file_content = read_file(some_file);

于 2012-04-19T19:48:24.407 に答える