`
cloudtech
  • 浏览: 4606133 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

【Q&A】getline读取行的行尾处理

 
阅读更多

windows和linux对文本文件的行尾有不同的约定。在windows系统中,行尾包含了两个字符,回车(carriage return, '\t')和换行(line feed, '\n')。这两个字符来自于从前的电传打字机,分别表示将写位置重新定位在首端,并跳转到下一行。在linux和unix、以及mac系统中,只保留了换行符,而没有回车符。这也是一些mac上的文本文件到windows系统上就无法正确换行的原因。


c++的getline函数作用是读取输入流中的字符,当遇到_Delim(The line delimiter)字符的时候,结束读取。通常_Delim默认为'\n'。看一下getline的源代码:

template<class _Elem,
class _Traits,
class _Alloc> inline
basic_istream<_Elem, _Traits>& __CLRCALL_OR_CDECLgetline(
basic_istream<_Elem, _Traits>& _Istr,
basic_string<_Elem, _Traits, _Alloc>& _Str)
{ // get characters into string, discard newline
return (getline(_Istr, _Str, _Istr.widen('\n')));
}

的确如此。那么在windows系统中,一行是以"\t\n"结尾的,前面的'\t'呢?'\n'前面的'\t'被读取到了字符串中。尝试了如下代码:

while (getline (in, sLine)) // 文件中的这一行只写了一个数字1(半角字符),即内容是 “1”
{

int iLength = sLine.lenght();

cout << iLength << endl;

打印出来的结果是“2”,表示除了文本内容‘1’之外,还有一个字符。debug看内容,字符的数值是13,是回车的ascii编码值。印证了前面的说法。


在文本处理中,尤其是中文处理中,有时候这个多出来的回车字符会带来麻烦,需要被去除掉。代码如下:

while (getline (in, sLine))
{
// remove '\t' at the end of sLine
char cLast = sLine.at (sLine.length()-1);

if (isspace(cLast))
sLine.erase (sLine.length()-1);


// do something to sLine
}

其中判断字符是否是回车的时候用到了isspace函数。这个函数是当字符为tab, line feed, home, form feed, carriage return的时候,都会返回true。再看一下isspace的实现,代码如下:

extern __inline int (__cdecl isspace) (
int c
)
{
if (__locale_changed == 0)
{
return __fast_ch_check(c, _SPACE);
}
else
{
return (_isspace_l)(c, NULL);
}
}

是调用 __fast_ch_check函数,将当前字符与_SPACE做“与”操作。_SPACE定义如下:

#define _SPACE 0x8 /* tab, carriage return, newline, */
/* vertical tab or form feed */

这就又有了个问题,空格的ascii值是32,十六进制表示为0x20,和0x8做与操作的结果是0啊。继续看__fast_ch_check的代码,它后来调用的是_chvalidator_l函数,实现如下:

extern "C" int __cdecl _chvalidator_l(
_locale_t plocinfo,
int c,
int mask
)
{
_LocaleUpdate _loc_update(plocinfo);


_ASSERTE((unsigned)(c + 1) <= 256);
if (c >= -1 && c <= 255)
{
return (_loc_update.GetLocaleT()->locinfo->pctype[c] & mask);
}
else
{
return (_loc_update.GetLocaleT()->locinfo->pctype[-1] & mask);
}
}


最终用到了系统locale信息,将字符c映射到pctype数组中的一个位置,这个位置的值是0x48,与0x8这个mask做与操作结果是1。就是说,对于空格,也能够判断出来。



分享到:
评论

相关推荐

    使用ifstream和getline读取文件内容[c++]

    c++、getline、每次读取一行txt; //读取方式: 逐词读取, 词之间用空格区分; //读取方式: 逐行读取, 将行读入字符数组, 行之间用回车换行区分; //读取方式: 逐行读取, 将行读入字符串, 行之间用回车换行区分

    ifstream和getline读取文件

    ifstream和getline读取文件

    getline 模板函数读取遇到分隔符后的多余的字符.pdf

    getline 模板函数读取遇到分隔符后的多余的字符

    C++:使用getline读取文本文件

    之前在使用C++中的getline读取文本文件时由于没有仔细看getline的定义,导致出了错:在读取文本文件时未读取到文件中的第一行。 错误的源代码如下: vectorreadfile&#40;string s1,vectorv1&#41; { ifstream infile...

    配置vim方便读取android反编译的smali文件

    55 :set foldexpr getline v:lnum [0] &quot; &quot;&amp;&amp;getline v:lnum [1] &quot;m &quot;&amp;&amp;getline v:lnum [2] &quot;e &quot;&amp;&amp;getline v:lnum [3] &quot;t &quot; #定义的规则 保存...

    VC++6.0编译器getline函数的bug处理

    微软已经确定vc++6.0中getline函数使用时有bug,并提出了解决方法!

    getline函数示例用法

    较简单的程序代码,示例了getline函数使用技巧

    c++ getline

    关于getline函数的详细方法说明,希望对刚学习c++的同胞们有点帮助

    Python linecache.getline()读取文件中特定一行的脚本

    比如: import linecacheprint linecache.getline... 您可能感兴趣的文章:python逐行读取文件内容的三种方法Python按行读取文件的简单实现方法Python3读取文件常用方法实例分析Python实现读取文件最后n行的方法Pyth

    Cin.getline终极用法1

    Cin.getline终极用法1

    C++中getline()的用法详解

    getline()用法 getline是C++标准库函数;它有两种形式,一种是头文件中输入流成员函数;一种在头文件中普通函数; 它遇到以下情况发生会导致生成的本字符串结束: (1)到文件结束,(2)遇到函数的定界符,(3)输入达到...

    浅谈C++中字符串输入get与getline的区别

    get和getline所属iostream类,作用是读取一整行,通过换行符确定读取结束,他们都可以读取空格。 2、get与getline区别 getline会在读取结束后舍弃换行符,而get回将换行符保留到输入序列中。 char arr[100]; cout&...

    getline函数输入要击两次回车的解决办法

    这个getline函数输入要击两次回车的解决办法不错..有点实用

    C++ cin.getline及getline()用法详解

    例如,要读取一行输入,必须使用 cin.getline 而不是 getline 函数。这两个的名字看起来很像,但它们是两个不同的函数,不可互换。 与 getline 一样,cin.getline 允许读取包含空格的字符串。它将继续读取,直到它...

    基于getline()函数的深入理解

    getline()函数的功能是从文件中获取行信息,即每次读取一行信息。 因为我使用getline()函数的目的是获取本地网卡信息,即eth0的信息,从而判断启动机子时是否查了网线(本来可以从驱动里做,但应用层可以搞定,就不...

    opengl读取stl文件

    STL是三维模型常用的文件格式。...再用标准库string类型中的getline逐行读取绑定的STL文件;最后, 应用 OpenGL 中绘制三角面片编程技术实现对 STL 文件格式的直观显示。通过试验验证了读取和显 示效果。

    C++读取到回车换行符问题处理

    C的话用getchar()就好了,但是用C++的时候发现CIN似乎不接受回车符……搜索解决方法的时候很多人都建议将getline,然后处理数组或者定义一个流什么的,但是这样一行可能很长,要占用很多空间。有没有别的办法?

    AST.getLine()I 解决方案

    java.lang.NoSuchMethodError: antlr.collections.AST.getLine()I 解决方案

    Python3实现从文件中读取指定行的方法

    本文实例讲述了Python3实现从文件中读取指定行的方法。分享给大家供大家参考。具体实现方法如下: # Python的标准库linecache模块非常适合这个任务 import linecache the_line = linecache.getline('d:/FreakOut....

Global site tag (gtag.js) - Google Analytics