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。就是说,对于空格,也能够判断出来。
分享到:
相关推荐
c++、getline、每次读取一行txt; //读取方式: 逐词读取, 词之间用空格区分; //读取方式: 逐行读取, 将行读入字符数组, 行之间用回车换行区分; //读取方式: 逐行读取, 将行读入字符串, 行之间用回车换行区分
ifstream和getline读取文件
getline 模板函数读取遇到分隔符后的多余的字符
之前在使用C++中的getline读取文本文件时由于没有仔细看getline的定义,导致出了错:在读取文本文件时未读取到文件中的第一行。 错误的源代码如下: vectorreadfile(string s1,vectorv1) { ifstream infile...
55 :set foldexpr getline v:lnum [0] " "&&getline v:lnum [1] "m "&&getline v:lnum [2] "e "&&getline v:lnum [3] "t " #定义的规则 保存...
微软已经确定vc++6.0中getline函数使用时有bug,并提出了解决方法!
较简单的程序代码,示例了getline函数使用技巧
关于getline函数的详细方法说明,希望对刚学习c++的同胞们有点帮助
比如: import linecacheprint linecache.getline... 您可能感兴趣的文章:python逐行读取文件内容的三种方法Python按行读取文件的简单实现方法Python3读取文件常用方法实例分析Python实现读取文件最后n行的方法Pyth
Cin.getline终极用法1
getline()用法 getline是C++标准库函数;它有两种形式,一种是头文件中输入流成员函数;一种在头文件中普通函数; 它遇到以下情况发生会导致生成的本字符串结束: (1)到文件结束,(2)遇到函数的定界符,(3)输入达到...
get和getline所属iostream类,作用是读取一整行,通过换行符确定读取结束,他们都可以读取空格。 2、get与getline区别 getline会在读取结束后舍弃换行符,而get回将换行符保留到输入序列中。 char arr[100]; cout&...
这个getline函数输入要击两次回车的解决办法不错..有点实用
例如,要读取一行输入,必须使用 cin.getline 而不是 getline 函数。这两个的名字看起来很像,但它们是两个不同的函数,不可互换。 与 getline 一样,cin.getline 允许读取包含空格的字符串。它将继续读取,直到它...
getline()函数的功能是从文件中获取行信息,即每次读取一行信息。 因为我使用getline()函数的目的是获取本地网卡信息,即eth0的信息,从而判断启动机子时是否查了网线(本来可以从驱动里做,但应用层可以搞定,就不...
STL是三维模型常用的文件格式。...再用标准库string类型中的getline逐行读取绑定的STL文件;最后, 应用 OpenGL 中绘制三角面片编程技术实现对 STL 文件格式的直观显示。通过试验验证了读取和显 示效果。
C的话用getchar()就好了,但是用C++的时候发现CIN似乎不接受回车符……搜索解决方法的时候很多人都建议将getline,然后处理数组或者定义一个流什么的,但是这样一行可能很长,要占用很多空间。有没有别的办法?
java.lang.NoSuchMethodError: antlr.collections.AST.getLine()I 解决方案
本文实例讲述了Python3实现从文件中读取指定行的方法。分享给大家供大家参考。具体实现方法如下: # Python的标准库linecache模块非常适合这个任务 import linecache the_line = linecache.getline('d:/FreakOut....