web-dev-qa-db-ja.com

Struct Stat()の使用

Stat()を使用してファイルに関する情報をキャプチャする方法を正確に理解しようとしています。私が必要としているのは、ファイルに関する情報のいくつかのフィールドを印刷できるようにすることです。そう..

 #include <iostream>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 using namespace std;

 int main() {
     struct stat buf;
     stat("file",&buf);
               ...
     cout << st_dev << endl;
     cout << st_ino << endl;
     cout << st_mode << endl;
     cout << st_nlink << endl;
     cout << st_uid << endl;
     cout << st_gid << endl;
     cout << st_rdev << endl;
     cout << st_size << endl;
     cout << st_blksize << endl;
     cout << st_blocks << endl;
     cout << st_atime << endl;
     cout << st_mtime << endl;
     cout << st_ctime << endl;
     ...
 }

私はこれを行う方法について完全に混乱しています。 &bufがstatのパラメータであるのはなぜですか?この情報をメモリに保存する必要はありません。C++プログラム内に出力フィールドが必要なだけです。構造体に含まれる情報にアクセスするにはどうすればよいですか? bufは実際にstat()から返された情報を含むことになっていますか?

10
Dan Snyder

はい、ここではbufが出力パラメータとして使用されています。結果はbufに格納され、statの戻り値は、stat操作が成功したか失敗したかを示すエラーコードです。

statはC用に設計されたPOSIX関数であり、例外などの帯域外エラー報告メカニズムをサポートしていないため、このように行われます。 statreturned構造体の場合、エラーを示す方法はありません。このアウトパラメータメソッドを使用すると、呼び出し元は結果を保存する場所を選択することもできますが、これは2番目の機能です。ここで行ったように、通常のローカル変数のアドレスを渡すことはまったく問題ありません。

他のオブジェクトと同じように、構造体のフィールドにアクセスします。あなたは少なくともオブジェクト表記に精通していると思いますか?例えば。 statと呼ばれるbuf構造体内のst_devフィールドには、buf.st_devがアクセスします。そう:

cout << buf.st_dev << endl;

等.

12
Tyler McHenry

別のプロジェクトのために、私はあなたが必要とするものに似た何かをする小さな機能を作り上げました。 sprintstatf を見てください。

使用例は次のとおりです。

#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>

#include "sprintstatf.h"

int
main(int argc, char *argv[])
{
    char *outbuf = (char *)malloc(2048 * sizeof(char));
    struct stat stbuf;
    char *fmt = \
        "st_atime (decimal) = \"%a\"\n"
        "st_atime (string)  = \"%A\"\n"
        "st_ctime (decimal) = \"%c\"\n"
        "st_ctime (string)  = \"%C\"\n"
        "st_gid   (decimal) = \"%g\"\n"
        "st_gid   (string)  = \"%G\"\n"
        "st_ino             = \"%i\"\n"
        "st_mtime (decimal) = \"%m\"\n"
        "st_mtime (string)  = \"%M\"\n"
        "st_nlink           = \"%n\"\n"
        "st_mode  (octal)   = \"%p\"\n"
        "st_mode  (string)  = \"%P\"\n"
        "st_size            = \"%s\"\n"
        "st_uid             = \"%u\"\n"
        "st_uid             = \"%U\"\n";

    lstat(argv[1], &stbuf);

    sprintstatf(outbuf, fmt, &stbuf);
    printf("%s", outbuf);

    free(outbuf);
    exit(EXIT_SUCCESS);
}

/* EOF */
4
Jon Bringhurst

この質問はコメントするのに古い方法かもしれませんが、私はこれを参照として投稿しています

Stat()関数について十分に理解するために、stat参照を渡す理由と、さらに重要なエラー処理は、以下のリンクで適切に説明されています

stat-ファイルのステータスを取得

2
Ram

コードにいくつかのエラーがあります:

  • 単一の「f」を含む&bufが必要です。
  • あなたは例えば言う必要がありますbuf.st_devは構造体変数のフィールドであるため、印刷時はst_dev

bufはスタック上のローカル変数であるため、永続的に「値をメモリに保存」するのではなく、その変数がスコープ内にある限りです。

これは、通常、CおよびC++で複数の値を返す方法です。構造体へのポインターを渡すと、呼び出される関数は、計算した値を構造体に入力します。

1
unwind

bufは、最初のパラメーターで渡したファイルに関する情報とともにstatがロードする構造体です。 &bufをここに渡します。スタックにローカル変数としてbufを割り当てています。データをロードできるようにするには、stat関数にポインターを渡す必要があります。

st_*のすべての変数はstruct statオブジェクトの一部であるため、ローカルのbuf変数を介してbuf.st_uidなどとしてアクセスする必要があります。

1
RC.