机器学习和生物信息学实验室联盟
标题:
序列文本行末LF, CR, and CRLF的平台差异性及处理
[打印本页]
作者:
xingpengwei
时间:
2017-4-10 19:03
标题:
序列文本行末LF, CR, and CRLF的平台差异性及处理
本帖最后由 xingpengwei 于 2017-4-10 19:03 编辑
生物信息涉及很多序列文本的处理,例如fasta格式的文件,特别涉及不同平台间传递处理文本时,文末的回车换行符(Carriage-Return Line-Feed 回车换行,CRLF的意思就是回车(CR, ASCII 13, \r) 换行(LF, ASCII 10, \n))容易引起一些问题。
在Windows中:
'\r' 回车,回到当前行的行首,而不会换到下一行,如果接着输出的话,本行以前的内容会被逐一覆盖;
'\n' 换行,换到当前位置的下一行,而不会回到行首;
Unix系统里:
每行结尾只有“<换行>”,即"\n";Windows系统里面,每行结尾是“<回车><换行>”,即“\r\n”;
Mac系统里:
每行结尾是“<回车>”,即"\r";
文本显示一般都不是大问题,无非Unix的文本用普通的windows的notepad会连成一行。
主要编程中一定要注意,一般涉及size之类的函数或者处理fasta的title获取label位置时,即使是同一个开发环境下(例如pycharm)不同平台会出现差异。那最近处理序列用到的C++的getline函数举例:
Mac系统下传过来的文本,在Unix系统下使用getline函数得到的line末尾可能会多出\r,size()函数也会多1,所以为了应该各种情况就得分类处理或者避免使用size之类的函数。
例如处理title获取label时,>124|0,java使用split,c++没有split则可以选择使用find获取‘|’的位置或判断后一位是不是0来判断
当处理序列行时,则需要分类处理,检查行末是否带有\r之类的字符。
对于c++可以写一个函数统一处理(见:
Getting std :: ifstream to handle LF, CR, and CRLF?
):
std::istream& safeGetline(std::istream& is, std::string& t)
{
t.clear();
// The characters in the stream are read one-by-one using a std::streambuf.
// That is faster than reading them one-by-one using the std::istream.
// Code that uses streambuf this way must be guarded by a sentry object.
// The sentry object performs various tasks,
// such as thread synchronization and updating the stream state.
std::istream::sentry se(is, true);
std::streambuf* sb = is.rdbuf();
for(;;) {
int c = sb->sbumpc();
switch (c) {
case '\n':
return is;
case '\r':
if(sb->sgetc() == '\n')
sb->sbumpc();
return is;
case EOF:
// Also handle the case when the last line has no line ending
if(t.empty())
is.setstate(std::ios::eofbit);
return is;
default:
t += (char)c;
}
}
}
复制代码
其他语言也要注意,之前用python也出现过这类问题,一旦程序出问题,推荐debug查看line,log输出有时可能发现不了。
作者:
shixiang
时间:
2017-4-30 21:16
有简便的方法:
java下用String.trim()直接处理;
python下可以用strip()直接处理。
欢迎光临 机器学习和生物信息学实验室联盟 (http://123.57.240.48/)
Powered by Discuz! X3.2