C++ getline使用重定向命令从stdin读入的字符串<&引用;“从输入文件”未正确附加

C++ getline使用重定向命令从stdin读入的字符串<&引用;“从输入文件”未正确附加,c++,string,stdin,io-redirection,C++,String,Stdin,Io Redirection,问题陈述 我想在另一个使用getline函数从stdin读入的字符串“冰激凌”后面附加一个字符串“太棒了!” 因此,制作“冰淇淋太棒了!” 如果输入是手动输入的,则追加操作可以完美地工作 但是,如果输入是通过重定向命令“从文件中获取的,请注意该行甚至不包含假定为前导的输出“err\t:\t”,但err的输出显示了它应该在哪里 这只能是因为输入文件包含前导回车符'\r'akknowledgement 很高兴提到,'\r'可以出现在字符串中 问题来源 有道理,Linux、Macintosh和Wind

问题陈述

我想在另一个使用getline函数从stdin读入的字符串“冰激凌”后面附加一个字符串“太棒了!”

因此,制作“冰淇淋太棒了!”

如果输入是手动输入的,则追加操作可以完美地工作


但是,如果输入是通过重定向命令“从文件中获取的,请注意该行甚至不包含假定为前导的输出
“err\t:\t”
,但
err
的输出显示了它应该在哪里


这只能是因为输入文件包含前导回车符
'\r'

akknowledgement

很高兴提到,
'\r'
可以出现在字符串中

问题来源

有道理,Linux、Macintosh和Windows有不同的行终止符,因此当我们希望将文件从一个系统传输到另一个系统并期望它们正常工作时,可能会出现一些问题

这个问题解释得很好:

这正是发生的事情。我使用Notepad.exe创建了该文件,因此自动为其分配了一个CRLF行终止符。然而,由于我使用(基本上是在Windows 10内运行的Ubuntu)编译该程序,因此创建的可执行文件
a.out
是linux可执行文件

将带有CRLF行终止符的文件重定向到可执行stdin会导致此问题

在使用MinGW或MSYS2之后,迁移到WSL的用户可能会面临这个特殊问题

因为,MinGW和MSYS2在CRLF编码方面工作得很好,但WSL没有

修复

只需使用名为
unix2dos
dos2unix
的工具更改行终止符即可

顾名思义,它们将文本文件转换为与dos和unix兼容 基于操作系统

  • 使用使用Linux/WSL创建的文件使其与Windows可执行文件兼容时,请使用unix2dos
  • 使用使用Windows创建的文件使其与Linux/WSL可执行文件兼容时,请使用dos2unix
演示

C:\test>wsl g++test.cpp-o a.out-std=C++11
C:\test>wsl unix2dos in-test.in
unix2dos:正在将in-test.in文件转换为DOS格式。。。
C:\test>wsl文件in-test.in
in-test.in:ASCII文本,带CRLF行终止符
C:\test>wsl./a.outwsl dos2unix in-test.in
dos2unix:正在将in-test.in文件转换为Unix格式。。。
C:\test>wsl文件in-test.in
in-test.in:ASCII文本
C:\test>wsl./a.out
结果

  • WSL创建的可执行文件最初不能与带有CRLF行终止符的输入文件一起工作,然后

  • 通过使用工具
    dos2unix
    将文件的行终止符更改为与Linux兼容的行终止符,从而使程序成功运行。因此,修复程序可以正常工作


Wow!在发布问题后的5秒钟内,在5个视图内,投了2次反对票。错误在哪里?这正是您正在使用的代码?哪个版本的gcc?哪个操作系统?代码本身没有问题。
#include<iostream>

int main()
{
    // err : will be read from stdin using getline
    // err : is expected to fail in appending
    std::string err;

    // ok  : will be modified internally
    // ok  : is expected to succeed in appending
    std::string ok = "Pancakes";

    std::cout<<"Before executing  std::getline..."<<std::endl;
    std::cout<<"err \t:\t"<<err<<std::endl;
    std::cout<<"ok \t:\t"<<ok<<std::endl;
    std::cout<<"-------------------"<<std::endl;

    // we now use getline to read in string value for err
    // stdin can have any string , let's assume it is "Ice creams"
    std::cout<<"-------------------"<<std::endl;
    std::cout<<"Please enter string manually or < from file "<<std::endl;
    std::getline(std::cin,err);
    std::cout<<"-------------------"<<std::endl;


    std::cout<<"After executing std::getline..."<<std::endl;
    std::cout<<"err \t:\t"<<err<<std::endl;
    std::cout<<"ok \t:\t"<<ok<<std::endl;
    std::cout<<"-------------------"<<std::endl;

    //-------------------------------------------//
    //               THE PROBLEM                 //
    //-------------------------------------------//
    // we try to append to err
    err += " are awesome !";
    // we try to append to ok
    ok  += " are awesome !";

    std::cout<<"After executing append operation..."<<std::endl;
    std::cout<<"Where,the '+=' operator is used..."<<std::endl;
    std::cout<<"err \t:\t"<<err<<std::endl;
    std::cout<<"ok \t:\t"<<ok<<std::endl;
    std::cout<<"-------------------"<<std::endl;


    return 0;
}