0

このコードを取得して、入力ファイルを2つのファイルに分割しようとしています。コードを分割して、1つの新しいファイルにすべての奇数文字が含まれ、もう1つのファイルにすべての偶数文字が含まれるようにします。私のコードではエラーは発生せず、2つの新しいファイルが生成されますが、2つの新しいファイルには何も含まれていません。私は自分のコードの何が悪いのか疑問に思っています(私はそれがたくさん間違っていると確信しています)。私はまだプログラミングにかなり慣れていません。

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

void split(char sourceFile[], char destFile1[], char destFile2[]) {
    int chars = 0;
    ifstream sFile;
    sFile.open(sourceFile);
    ofstream file1;
    file1.open(destFile1);
    ofstream file2;
    file2.open(destFile2);

    while (!sFile.eof()) {
        sFile.read(sourceFile + chars, 1);

        cout << sourceFile[chars];
        if (chars % 2 == 0) {
            file1 << sourceFile[chars];
        } else {
            file2 << sourceFile[chars];
        }
        chars++;


    }
}

int main() {
    split("text.txt", "one.txt", "two.txt");
    return 0;
}
4

5 に答える 5

1

いくつかの非常に深刻な問題:

  • あなたはループ制御は無意味です。'istream :: eof()'がtrueになるときは明確に定義されていませんが、バイトごとに読み取る場合は、実行しているように、必要以上にループに入る可能性があります。

  • 関連する問題は、読み取りが成功したことを確認しないことです。読み取りの成功は、ループ制御である必要があります。

  • 未定義の動作である文字リテラルを読み込んでいます(多くのシステムでクラッシュします)。十分な読み取りの後、リテラルの終わりを超えて、未定義のメモリに読み取っています。読み取りには、実際にはローカルバッファを使用する必要があります。

  • エラーチェックは行いません。少なくとも、ファイルが正常に開かれたことを確認し、出力ファイルを閉じて、閉じた後のステータスをチェックして、書き込みが機能していることを確認する必要があります。

私はおそらく線に沿って何かを使用するでしょう:

void
split( std::string const& source, 
       std::string const& dest1,
       std::string const& dest2 )
{
    std::istream in( source.c_str() );
    if ( ! in.is_open() ) {
        //  Cannot open source...
    }
    std::ostream out1( source.c_str() );
    if ( ! out1.is_open() ) {
        //  Cannot create dest1
    }
    std::ostream out2( source.c_str() );
    if ( ! out2.is_open() ) {
        //  Cannot create dest2
    }
    std::ostream* currentOut = &out1;
    std::ostream* otherOut = &out2;
    char ch;
    while ( in.get( ch ) ) {
        currentOut->put( ch );
        std::swap( currentOut, otherOut );
    }
    out1.close();
    if ( !out1 ) {
        //  Write error on dest1...
    }
    out2.close();
    if ( !out2 ) {
        //  Write error on dest2...
    }
}

(ご覧のとおり、コピーを実行する実際のループは非常に単純です。ほとんどのコードはエラー処理に関係しています。)

于 2012-11-22T23:43:28.777 に答える
1

それには多くの間違いがあります(あなたが言ったように)

ifstream1)ファイルに出力する場合は、すべてのファイルを使用しますofstream

2)コードの変数としてファイル名を使用しようとしないでください。新しいchar変数を宣言するだけです。

3)get not readを使用して、単一の文字を読み取ります。

4)ファイルの終わりを正しくテストします。

5)ループ内のファイルを閉じないでください。実際、ファイルをまったく閉じないでください。関数を終了すると自動的に閉じられます。

6)いったい何chars%2 == 5についてですか?それは決して真実ではありません。

それをまとめる

char ch;
while (sFile.get(ch))
{
    if (chars % 2 == 0)
        file1 << ch;
    else
        file2 << ch;
    chars++;
}
于 2012-11-22T22:41:13.063 に答える
0

あなたのインデントは誤解を招きます!ファイルclose()呼び出しは、ループ内にあります。

そして:i % 2 == 5決して真実ではありません。どうif (i % 2 == 0) { ... } else { ... }ですか?

于 2012-11-22T22:36:44.170 に答える
0

';'を忘れました スペルミスのある'sourcFile'

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

void split(char sourceFile[], char destFile1[], char destFile2[])
{
int chars = 0;

ifstream sFile;
sFile.open (sourceFile);

ofstream file1;
file1.open (destFile1);

ofstream file2;
file2.open (destFile2);

while (!sFile.eof())
{
    sFile.read(sourceFile+chars,1); // forgot ';'

    cout << sourceFile[chars];
    if (chars % 2 == 0)
    {
        file1<< sourceFile[chars];
    }
    else if(chars % 2 == 5)
    {
        file2 << sourceFile[chars]; // misspelled 'sourcFile'
    }
    chars++;

sFile.close();
file1.close();
file2.close();
}

}

int main()
{
split("text.txt", "one.txt", "two.txt");
return 0;
}

ただし、出力はテストしていません。それがうまくいかない場合は、自分で試すための入力ファイルを教えていただけますか?

于 2012-11-22T22:39:49.447 に答える
0

質問への答えではありませんが、目的の目標を実装するプログラムのややコンパクトなバージョンです。

#include <algorithm>
#include <iterator>
#include <fstream>
#include <functional>

int main()
{
    typedef std::ostreambuf_iterator<char> oit;
    unsigned int chars(0);
    std::for_each(std::istreambuf_iterator<char>(
                      std::ifstream("text.txt") >> std::noskipws),
                  std::istreambuf_iterator<char>(),
                  std::bind([=](oit _1, oit _2, char c) mutable {
                          *(chars++ % 2? _1: _2)++ = c; },
                      oit(std::ofstream("one.txt") << std::dec),
                      oit(std::ofstream("two.txt") << std::dec),
                      std::placeholders::_1));
}
于 2012-11-22T23:11:28.040 に答える