6

Apache ログを読み取る Linux コンソール アプリの作成に問題があります。

bash スクリプトの引数を処理する必要があります。最後の引数はログ ファイルへのパスです。私の問題は、ファイルが存在しない場合、例外をスローしたいということです。

しかし、ファイルを読み取り専用モードで開こうとすると、失敗する代わりにファイルが作成されます!

コードは次のとおりです。

// logreader.h

#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <stdexcept>


class LogReader
{
    public:
        LogReader(int, const char **);
        virtual ~LogReader();

        // ...

    private:
        std::ifstream log_;
};

// logreader.cpp

#include <logreader.h>

LogReader::LogReader(int argc, const char ** argv):
    log_()
{
    log_.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    for (int i = 1; i < argc; ++i)
    {
        std::string arg(argv[i]);
        if (i == argc - 1)
        {
            try
            {
                log_.open(arg.c_str(), std::ifstream::in);
            }
            catch (std::ifstream::failure)
            {
                throw std::runtime_error("The file " + arg + " wasn't opened");
            }
        }
    }
}

LogReader::~LogReader()
{
}

// main.cpp

#include <logreader.h>

int main(int argc, const char ** argv)
{
    LogReader(argc, argv);
    return 0;
}

スクリプト呼び出し:

jmcomets $ ./test -g -l
jmcomets $ ls -l
-rw-rw-r-- 1 jmcomets jmcomets     0 Nov 14 22:41 -l 
4

4 に答える 4

3

を開いているので、27.9.1.9 [ifstream.members] パラグラフ 4 に従って(または の他のスペル)std::ifstreamを追加する必要があります。フラグは、への呼び出しによって自動的に追加されます。anまたは anは(27.9.1.13 [ofstream.members] paragrpah 3) または(27.9.1.17 [fstream.members] paragrpah 3)を自動的に追加することに注意してください。どちらも、存在しない場合は新しいファイルが作成されます。 (そして、書き込み権限などがあります)。std::ios_base::instd::ios_base::openmodeopen()std::ofstreamstd::fstreamstd::ios_base::outstd::ios_base::in | std::ios_base::out

投稿したコードが新しいファイルを作成する場合、標準 C++ ライブラリの実装が間違っています: フラグのみが指定されている場合、ファイルは(27.9.1.4 [filebuf.members] 段落std::ios_base::inのオープン モード"r"を使用して「あたかも」開かれます) fopen()5)。次に、 (7.21.5.3 段落 3)fopen()のオープン モードを取得したときに、新しいファイルを作成しません。"r"

于 2012-11-14T22:27:28.330 に答える
2

failbit次の例外フラグで設定できますifstream

std::ifstream log;
log.exceptions ( std::ifstream::failbit );
try {
    log.open ("test.txt");
}
catch (std::ifstream::failure e) {
    std::cout << "Exception opening/reading file\n";
}

ソース

私はテストしましたが、ファイルが見つからない、読み取り権限がないなど、ファイルを開くことができない場合は例外ifstreamをスローします。failure読み取り専用で開きます

于 2012-11-14T21:27:52.160 に答える
0

Linux と互換性のあるもので編集します。

書き込む前に fopen で開いてみてください。ファイルが DNE の場合、FILEポインタは null になります。

FILE * file;
file = fopen ("myfile.txt","r");

if (file == NULL)
   //throw if fopen didn't already.
else
    //do stuff with my file
于 2012-11-14T21:26:45.290 に答える
0

次のように、ifstream::in を 2 番目のパラメーターとして指定する必要があります。

log.open(arg.c_str(), ifstream::in)

次のこともできます。

std::ifstream log(arg.c_str(), ifstream::in);

への呼び出しをスキップしますopen()

于 2012-11-14T21:30:25.853 に答える