1

次の C コードを C++ に翻訳したいと思います。

FILE *fp = NULL;
fp = fopen("./filename", "r");
int i = 0;
fscanf(fp, "%d\n", &i);
uint16_t j = (uint16_t) i;

これは私がこれを思いついたものです:

  ifstream file;
  string filename = "./filename";

  file.open(filename.c_str(), ios::in);
  errno = 0;
  if (file.fail()) {
      int tmp = errno;
      std::cout << file.c_str () << " not found: strerror(" << tmp << "): " << strerror(tmp) );
  }
  int i = 0;
  file >> i >> std::endl;       
  uint16_t j = (uint16_t) i;

構文が正しいか改善可能か、さらに重要なことに、あらゆる種類の入力に対して安全かどうかを知りたいです。

4

2 に答える 2

2

正確に同等のものは次のとおりです。

std::ifstream fs( "./filename" );
int i = 0;
fs >> i >> std::ws;
uint16_t j = i;

これがあなたが本当に望んでいるものかどうかは別の問題です: "\n"フォーマット文字列で a を使用するfscanfことは (少なくとも私には)、'\n'任意の空白ではなく単一の を本当に読みたいことを示唆しています。ただし、の"\n"意味はfscanf、次の非空白までスキップすることです。scanf(インタラクティブな入力の場合、これは実際の問題になる可能性があります。なぜなら、空白以外の文字またはファイルの終わりに遭遇するまで、あなたの — または上記の私の代替 — から戻らないからです。ファイルからの入力の場合、それは問題ではないかもしれません。)

行指向の入力を読み取る場合、古典的な解決策は、 を使用してから を使用 std::getlinestd::istringstreamて解析することです。

于 2012-04-23T16:20:35.813 に答える
2
int read_int(const std::string file_name) {
    std::ifstream file(file_name); //the file will close itself on destruction
    std::uint16_t i;
    //extract type, don't worry about what it is it will either compile or not
    if(!(file >> i)) { //Catch failure
         //or however you wish to deal with it.
         throw std::runtime_error("can't read file");
    }
    return i;
}

int main() {
    try{
        std::uint16_t i=read_int("./filepath");
        //do with i...
    }
    catch(const std::exception& e) {
         std::cerr << e.what() << std::endl;
         return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

C++11 を使用していない場合はc_str()、ファイルを開くために を使用する必要がありますが、文字列メソッドが推奨されます。

編集: fstream は自分自身を閉じます。自分で閉じる必要はありません。そうする必要がある場合に備えて機能がありますが、RAII セマンティクスに依存する方がはるかに優れています。

http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization

RAII は、構築時にファイルを開く必要があり、破棄時に閉じるように指示します。これにより、バグを防止する無効な (EOF を除く、ファイルが見つからない...) fstream オブジェクトが存在しないことが保証されます。RAII は C++ の基本的な構成要素であり、リソースが関係するあらゆる場所で使用する必要があります。

fstream デストラクタのドキュメントは次のとおりです。

http://en.cppreference.com/w/cpp/io/basic_fstream

basic_fstream と関連するバッファを破棄し、ファイルを閉じます

于 2012-04-23T15:47:11.197 に答える