C++ - 损坏的字符串

C++ - Corrupted String

我对 C++ 很陌生,但我已经习惯了使用 R 语言进行一些编码。几周前,我开始组装一个应该复制和重命名文件对 (.seq/.ab1) 的小应用程序。 DNA 测序仪分析的结果(手动重命名数百个将是真正的时间浪费,特别是因为我们有包含它们新名称的列表)。

一切似乎都很好,但是新文件(那些复制的文件)的名称中出现了 "special character"(就在文件类型之前),看起来像 space,但是它不是(我用 space 替换了它,并且文件打开正确)。删除后,该文件可以被其关联的应用程序打开,但是,应用程序指责该文件已损坏。

问题似乎出在与 ostringstream::str 成员函数相关的代码中,但老实说我不知道​​如何解决。我想知道在我追加文件类型之前它是否没有在那里插入空字符...

这是负责的代码部分。它从一个 2 列的 csv 文件中获取新旧名称,数据以“;”分隔。原始数据和新的(重命名的文件)数据保存在不同的目录中,这就是我需要在 for 循环中创建一个包含每个文件路径的字符串的原因。我打算稍后检查新旧文件内容,可能使用 memcmp。但首先我需要将它们正确重命名。

我在 Ubuntu 14.04(64 位)机器上,编译器是 gcc 4.8.4。我已经为可能糟糕的编码和糟糕的英语道歉,我不是母语人士(实际上是作家)。

    fNew.open(filename);
    std::ostringstream oldSeqName (std::ostringstream::ate);
    std::ostringstream newSeqName (std::ostringstream::ate);
    std::ostringstream oldAb1Name (std::ostringstream::ate);
    std::ostringstream newAb1Name (std::ostringstream::ate);

    std::fstream log;
    time_t now = time(0);

    for (std::string nOld, nNew; getline(fNew, nOld, ';') && getline(fNew, nNew); )
    {
        std::cout << "Old Name: " << nOld << " -> New Name: " << nNew << std::endl;

        // Keep a log of the name changes
        log.open("NameChangesLog.txt", std::fstream::out | std::fstream::app);
        log << ctime(&now) << " - " <<  "Old Name: " << nOld << " -> New Name: " << nNew << std::endl;
        log.close();

        // Create old seq files paths string
        oldSeqName.str(nOld);
        oldSeqName << ".seq";
        std::string osn = "./Seq/" + oldSeqName.str();

        // Create new seq files paths string
        newSeqName.str(nNew);
        newSeqName << ".seq";
        std::string nsn = "./renamed/" + newSeqName.str();

        std::ifstream ifseq(osn, std::ios::binary);
        std::ofstream ofseq(nsn, std::ios::binary);

        ofseq << ifseq.rdbuf();

        ifseq.close();
        ofseq.close();

        // Create old ab1 files paths string
        oldAb1Name.str(nOld);
        oldAb1Name << ".ab1";
        std::string oan = "./Seq/" + oldAb1Name.str();

        // Create new abq files paths string
        newAb1Name.str(nNew);
        newAb1Name << ".ab1";
        std::string nan = "./renamed/" + newAb1Name.str();

        std::ifstream ifab1(oan, std::ios::binary);
        std::ofstream ofab1(nan, std::ios::binary);

        ofab1 << ifab1.rdbuf();

        ifab1.close();
        ofab1.close();

    }

    fNew.close();

您可能忘记 trimgetline 返回的值,因此它们可能仍然包含空格。空白可能很难被应用程序拾取。

列表文件是在Windows机器上准备的吗?在那种情况下,它将以 DOS 行结尾 (\r\n) 并且不太适合 Unix 上的 getline。您看到的角色很可能是 \r。确保在将列表文件提供给程序之前使用 dos2unix 实用程序