换行符问题

昨天帮人调试一个perl程序。程序运行在windows平台下,目的是,从参数文件中读入字符串,每个字符串都是单独一行的,读入后去掉行尾的换行符。大概的代码类似:

$name = <FILE>; 
chomp($name); 
print("$name"); 

现在的问题是$name读出来之后,打印出来却是空的。而且,如果读入的字符串是"fred",发现$name不等于"fred",这样导致下面的程序逻辑无法开展。

这个问题,后来发现,错误的原因不在程序,而在于使用的参数文件是在windows下面建立的,所以换行符是"/r/n",而不是unix标准的"/n"。

如果文件中有一行内容是"fred",$name在读入后,成为"fred/r/n",chomp去掉了$name的最后一个"/n",$name的值变成"fred/r"。

一般说,"/r"的意思是把输入指针放回到行首,"/n"的意思是把输入指针放到下一行的行首。
所以打印$name的时候,由于后面有一个"/r",光标回到行首,同时冲掉了已经输出的"fred",结果打印出来的就是一个空串。

而在后续程序中,$name后面始终带着一个"/r",所以无法进行程序逻辑了。自然导致出错。

事实上,如果用dos2unix把这个参数文件转换成unix样式的,程序就正常了。

其实,这个问题说到底,是perl的windows版没有考虑周全,是chomp实现的问题。比如windows平台下的libc就必然要把"/n"解释成为"/r/n",这种平台相关的东西,理论上,是不应该由程序员关心的。

但是在不能苛求工具的时候,就要苛求程序员了。

类似的问题,在linux下面是非常常见的,linux下面的许多工具都是假设"/n"为换行符的,那么windows文件中的"/r/n"就是一个灾难了。

比如,常写脚本的人可能会遇到这样难以理解的错误,执行run脚本,结果:

~# ./run 
: bad interpreter: No such file or directory 

这里最可能的原因就是run脚本是windows样式的,所以内核脚本的第一行找到的宿主shell文件名的后面多了一个"/r",自然exec会失败,那么打印错误信息的时候,本意也许是想

printf("%s: bad interpreter: No such file or directory/n", shell_name);

但是由于shell_name的后面有个"/r",所以打印出shell_name后,又重新回到行首,打印后面的信息。结果导致了这个莫名其妙的出错提示。

除了脚本,如果使用autoconf/automake工具的话,那么configure.in/Makefile.am这些需要被处理的文件都应该保证是"/n"换行的。

最后,说一下工具问题。
在windows下,很多编辑器都支持unix和windows之间的文件格式转换,比如ultra-edit32
在linux下,就是dos2unix/unix2dos这两个了。

需要说明的是最新版本的vim已经可以支持两种格式的文件,都会正常显示,而不是像旧版一样把"/r"显示成^M了,这样会让人不容易发现问题,所以留心一下vim下面的提示行,如果提示行中出现[dos]字样,那么这个文件就是windows样式的文件了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值