机器学习和生物信息学实验室联盟

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1612|回复: 1
打印 上一主题 下一主题

序列文本行末LF, CR, and CRLF的平台差异性及处理

[复制链接]
跳转到指定楼层
楼主
发表于 2017-4-10 19:03:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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?):
  1. std::istream& safeGetline(std::istream& is, std::string& t)
  2. {
  3.     t.clear();

  4.     // The characters in the stream are read one-by-one using a std::streambuf.
  5.     // That is faster than reading them one-by-one using the std::istream.
  6.     // Code that uses streambuf this way must be guarded by a sentry object.
  7.     // The sentry object performs various tasks,
  8.     // such as thread synchronization and updating the stream state.

  9.     std::istream::sentry se(is, true);
  10.     std::streambuf* sb = is.rdbuf();

  11.     for(;;) {
  12.         int c = sb->sbumpc();
  13.         switch (c) {
  14.         case '\n':
  15.             return is;
  16.         case '\r':
  17.             if(sb->sgetc() == '\n')
  18.                 sb->sbumpc();
  19.             return is;
  20.         case EOF:
  21.             // Also handle the case when the last line has no line ending
  22.             if(t.empty())
  23.                 is.setstate(std::ios::eofbit);
  24.             return is;
  25.         default:
  26.             t += (char)c;
  27.         }
  28.     }
  29. }
复制代码

        其他语言也要注意,之前用python也出现过这类问题,一旦程序出问题,推荐debug查看line,log输出有时可能发现不了。
               
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享
回复

使用道具 举报

沙发
发表于 2017-4-30 21:16:01 | 只看该作者
有简便的方法:
java下用String.trim()直接处理;
python下可以用strip()直接处理。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

机器学习和生物信息学实验室联盟  

GMT+8, 2024-11-1 19:23 , Processed in 0.066351 second(s), 18 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表