String C++;-损坏的字符串 我对C++很陌生,但我习惯了用R语言编写代码。几周前,我开始组装一个小应用程序,它可以复制和重命名文件对(.seq/.ab1)。DNA测序仪分析的结果(手动重命名数百个将是一种实时浪费,特别是因为我们有带有新名称的列表)

String C++;-损坏的字符串 我对C++很陌生,但我习惯了用R语言编写代码。几周前,我开始组装一个小应用程序,它可以复制和重命名文件对(.seq/.ab1)。DNA测序仪分析的结果(手动重命名数百个将是一种实时浪费,特别是因为我们有带有新名称的列表),string,c++11,ostringstream,String,C++11,Ostringstream,一切似乎都很好,但新文件(复制的文件)的名称中出现了一个“特殊字符”(就在文件类型之前),它看起来像一个空格,但它不是(我已将其替换为空格,并且文件已正确打开)。删除该文件后,该文件可以被其关联的应用程序拒绝,但使用它,应用程序会使该文件损坏 这个问题似乎来自与ostringstream::str成员函数相关的代码,但我真的不知道如何修复它。我想知道在我附加文件类型之前,是否在那里插入空字符 下面是代码的责任部分。它从一个2列csv文件中获取新旧名称,数据以“;”分隔。原始数据和新的(重命名的文

一切似乎都很好,但新文件(复制的文件)的名称中出现了一个“特殊字符”(就在文件类型之前),它看起来像一个空格,但它不是(我已将其替换为空格,并且文件已正确打开)。删除该文件后,该文件可以被其关联的应用程序拒绝,但使用它,应用程序会使该文件损坏

这个问题似乎来自与ostringstream::str成员函数相关的代码,但我真的不知道如何修复它。我想知道在我附加文件类型之前,是否在那里插入空字符

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

我在一台Ubuntu 14.04(64位)机器上,使用GCC4.8.4作为编译器。我已经为自己可能糟糕的编码和糟糕的英语辩解了,我不是以英语为母语的人(实际上是作家)

fNew.open(文件名);
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日志;
现在时间=时间(0);
对于(std::string nOld,nNew;getline(fNew,nOld,“;”)和&getline(fNew,nNew);)
{

std::cout您可能忘记了从
getline
返回的值,因此它们可能仍然包含空格。空格可能很难被应用程序识别。

列表文件是在Windows计算机上准备的吗?在这种情况下,它将以DOS行结尾(
\r\n
)并且不适合Unix上的getline。您看到的字符可能是
\r
。在将列表文件馈送到程序之前,请确保使用
dos2unix
实用程序。通过将字符强制转换为int,您可以检查此附加字符的ASCII代码。它将为您提供一些信息,说明该字符是否始终相同字符或随机的东西。我没有回答你的问题,但只是想说,这似乎更适合于小shell或perl脚本,而不是C++。Fiddle用<代码> SED和 BaseNeN/C++ >。新手程序员容易犯愚蠢的错误,很可能C++会很好地符合帐单。你可能不想用生产数据犯这样的错误。我的一位老教授曾经说过,答案可能比我们想象的要简单。“Arkadiy完全正确。这些文件是在Windows下生成的。或者在Ubuntu上运行解决了这个问题。非常感谢。或者以文本模式而不是二进制打开流。这在Windows上会有所不同。在Unix上运行时,文本模式没有帮助。Unix文本模式不知道\r\n
    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();