3

したがって、ファイル名を受け取る関数を含む.cppファイルがあり、ファイルの内容を含む文字列を返す必要があります(実際には内容を変更し、コードを変更してより理解しやすくしましたが、それは何の影響もありません私の問題)。問題は、それf.good()が戻っfalseてきて、ファイルを読み取るループが機能していないことです。コード :

#include "StdAfx.h"
#include "Form21.h"
#include <string>
#include <fstream>
#include <iostream>



    string ReadAndWrite(char* a){
    char filename[8];
    strcpy_s(filename,a);
    string output;
    char c;
    ifstream f(filename,ios::in);
    output+= "Example text"; // <-- this writes and returns just fine!
    c = f.get();

    while (f.good())
      { 

    output+= c;
    c= f.get();         
          }

    return output;
}

なぜこれが起こっているのか誰にも分かりますか?これは別の.cppファイルであることに関係がありますか(削除してもエラーは発生しません#include <fstream>)。たぶん、ループを作る別の種類の方法がありますか?これを修正する方法や、目標を達成するための別の方法についての提案をお待ちしております。

4

3 に答える 3

4

まず、受け取ったファイル名をそのままコピーする必要はありません。そのまま使用できます。while (stream.good())第二に、while (!stream.bad())while (stream)、 などの形式のほとんどすべてのループは、ほぼ確実にバグがあります。通常やりたいことは、一部のデータの読み取りが機能したかどうかを確認することです。

または、ループの使用をまったくスキップすることもできます。これを行うにはいくつかの方法があります。短いファイルでうまく機能するものは次のようになります。

string readfile(std::string const &filename) { 
    std::ifstream f(filename.c_str());   
    std::string retval;

    retval << f.rdbuf();
    return retval;
}

これは、数十キロバイト (程度) のデータまではうまく機能しますが、大きなファイルでは速度が低下し始めます。このような場合、通常、次ifstream::readの一般的な行に沿って、データを取得するために を使用します。

std::string readfile(std::string const &filename) {
    std::ifstream f(filename.c_str());

    f.seekg(0, std::ios_base::end);
    size_t size = f.tellg();

    std::string retval(size, ' ');
    f.seekg(0);
    f.read(&retval[0], size);
    return retval;
}

編集:個々の文字を処理する必要がある場合(読むだけでなく)、いくつかの選択肢があります。1 つは、すべてのデータを 1 つのフェーズで読み取り、別のフェーズで処理を行うフェーズに分割することです。別の可能性 (処理中に個々の文字を確認する必要がある場合) は、std::transformデータを読み取り、処理を実行し、出力を文字列に入れるなどの方法を使用することです。

struct character_processor { 
    char operator()(char input) { 
        // do some sort of processing on each character:
        return ~input;
    }
};

std::transform(std::istream_iterator<char>(f),
               std::istream_iterator<char>(),
               std::back_inserter(result),
               character_processor());
于 2012-04-24T15:57:08.853 に答える
0

strlen(a) が 7 を超えていないことを確認します...オーバーランfilenameして、存在しないファイル名を取得する可能性があります。

問題に関係なく、関数を書き直します:

string ReadAndWrite(string a) {  // string here, if you are into C++ already
    string filename;  // also here
    filename = a;  // simpler
    string output;
    char c;
    ifstream f(filename.c_str());  // no need for ios::in (but needs a char *, not a string
    output+= "Example text"; // <-- this writes and returns just fine!
    f >> c;  // instead c = f.get();

    while (f) // no need for f.good())
      { 

        output+= c;
        f >> c; // again, instead c= f.get();         
      }

    return output;
}
于 2012-04-24T15:45:24.143 に答える
-3

fopenの使用をお勧めしますか?http://www.cplusplus.com/reference/clibrary/cstdio/fopen/ファイル名を受け取り、ファイルポインタを返します。これにより、fgets を使用してファイルを 1 行ずつ読み取ることができますhttp://www.cplusplus.com/reference/clibrary/cstdio/fgets/

于 2012-04-24T15:46:14.657 に答える