首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows上的字符串大小不同于Linux上的字符串大小

问Windows上的字符串大小不同于Linux上的字符串大小
EN

Stack Overflow用户
提问于 2012-10-06 14:16:24
回答 3查看 3.4K关注 0票数 4

我偶然发现了string::substr.的奇怪行为通常,我在Windows 7上用Eclipse+MinGW编写代码,但是当我在笔记本上工作时,使用Linux (Ubuntu12.04)中的Eclipse+MinGW(Ubuntu12.04),我注意到结果不同。

我使用的是vector< string >,其中充满了文本行。其中一个步骤是从行中删除最后一个字符。

在win7 Eclipse中,我做到了:

代码语言:javascript
复制
for( int i = 0; i < (int)vectorOfLines.size(); i++ )
{
    vectorOfTrimmedLines.push_back( ((string)vectorOfLines.at(i)).substr(0, ((string)vectorOfLines.at(i)).size()-1) );
}

它的工作方式类似于预期(从每一行中删除最后一个字符)

但是在Linux中,这段代码不需要修剪。相反,我需要这样做:

代码语言:javascript
复制
//  -2 instead -1 character
vectorOfTrimmedLines.push_back( ((string)vectorOfLines.at(i)).substr(0, ((string)vectorOfLines.at(i)).size()-2) );

或者使用另一种方法:

代码语言:javascript
复制
vectorOfTrimmedLines.push_back( ((string)vectorOfLines.at(i)).replace( (((string)vectorOfLines.at(i)).size()-2),1,"",0 ));

当然,Linux方法在windows上的工作方式是错误的(修剪最后两个字符,或者在最后一个字符之前替换一个字符)。

问题似乎是myString.size()返回Windows中的字符数,但在Linux中它返回字符+ 1的数量。

作为C++和一般编程的新手,我想知道为什么会这样,以及如何做到与平台无关。

我想知道的另一件事是:哪种方法更好(更快) substr或替换

编辑:用来填充字符串的方法--我写的这个函数:

代码语言:javascript
复制
vector< string > ReadFile( string pathToFile )
{
    //  opening file
    ifstream myFile;
    myFile.open( pathToFile.c_str() );

    //  vector of strings that is returned by this function, contains file line by line
    vector< string > vectorOfLines;

    //  check if the file is open and then read file line by line to string element of vector
    if( myFile.is_open() )
    {
        string line;    //  this will contain the data read from current the file

        while( getline( myFile, line ) )    //  until last line in file
        {
            vectorOfLines.push_back( line );    //  add current line to new string element in vector
        }

        myFile.close(); //  close the file
    }

    //  if file does not exist
    else
    {
        cerr << "Unable to open file." << endl; //  if the file is not open output
        //throw;
    }

    return vectorOfLines;   //  return vector of lines from file
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-06 14:37:26

文本文件在不同的操作系统上并不相同。Windows使用两个字节的代码标记一行的末尾: 0x0D,0x0A.Linux使用一个字节,0x0A。getline (和大多数其他输入函数)知道它编译的操作系统的约定;当它读取操作系统用来表示行尾的字符时,它将字符替换为'\n‘。因此,如果在Windows下编写文本文件,行以0x0D、0x0A结尾;如果在Linux下读取该文本文件,getline会看到0x0D并将其视为正常字符,然后它会看到0x0A,并将其视为行尾。

因此,寓意是当您将文本文件从一个系统移动到另一个系统时,必须将它们转换为本机表示形式。ftp知道如何做到这一点。如果在虚拟框中运行,则必须在切换系统时手动进行转换。对于Unix命令行中的tr来说,这已经足够简单了。

票数 9
EN

Stack Overflow用户

发布于 2012-10-06 14:37:47

这是因为在Windows中,换行符由两个字符CR+LF表示,而在Linux上只有LF,而在Mac上(OSX之前)只有CR。

只要您只使用Linux系统上生成的Linux文件或Windows系统上生成的Windows文件,您就没有什么好担心的。但是,一旦您需要使用Windows上的Linux生成的文件(反之亦然),您就需要正确地处理换行符。

作为第一步,您需要以二进制模式std::ofstream infile( "filename", std::ios_base::binary);打开文件,然后有三个选项:

  1. 您需要为所有平台决定一个换行符,并一致使用,
  2. 您需要能够检测当前文件中使用的换行符(通常通过检查第一行使用的换行符来实现),将其保存在变量中,并将其传递给需要处理换行符的字符串函数,
  3. 告诉用户将文件转换到正确的换行符,例如使用dos2unix和unix2dos,或者如果文件传输涉及FTP,则使用ASCII模式

或者,如前所述,使用助推。

票数 4
EN

Stack Overflow用户

发布于 2012-10-06 21:50:38

在Windows和Linux/Unix中,行尾不一样- Windows使用两个字节,Linux使用一个字节。谷歌如何在.nix命令行上使用tr,您将看到如何转换它们。

祝好运!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12760574

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档