0

我正在尝试让此代码将输入文件拆分为两个文件。我希望将代码拆分,以便一个新文件包含所有奇数字符,另一个文件包含所有偶数字符。我的代码没有给我任何错误,它产生了两个新文件,但是这两个新文件中没有任何内容。我想知道我的代码有什么问题(我确信它有很多问题)。我对编程还是很陌生。

#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()' 变为真时,它的定义并不明确,但是当你正在逐字节读取时,它可能会导致你进入循环的次数比你想要的多一次。

  • 一个相关的问题是您没有验证读取是否成功。读取的成功应该是你的循环控制。

  • 您正在阅读字符文字,这是未定义的行为(并且会在很多系统上崩溃);经过足够的阅读后,您正在阅读文字末尾之外的内容,进入未定义的内存。您确实应该使用本地缓冲区进行读取。

  • 你不做任何错误检查。至少,您应该验证您是否已成功打开文件,并且您应该关闭输出文件,并在关闭后检查它们的状态,以确保写入工作正常。

我可能会使用类似的东西:

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

它有很多问题(如你所说)

1)ifstream如果要输出到文件,请使用所有文件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

不是问题的答案,而是实现预期目标的程序的紧凑版本:

#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 回答
0

你忘了一个';' 并且拼写错误的“源文件”

#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 回答