百科问答小站 logo
百科问答小站 font logo



如何解决windows上用fwrite()向文件写入内容时末尾的 问题? 第1页

  

user avatar   zorrolang 网友的相关建议: 
      

这个问题思考方式和方向不太正常,题目问的不明所以,问题描述所展现的也和题目描述不一致。特别是问题描述中提到:

“打开test.txt文件,发现文件末尾有个空格”
“在windows上该如何正确使用fwrite()函数,才能让生成的文本文件在linux上打开读取也格式正确呢?”

过于武断的得出判断,以及过于不太正常的思考解决问题的方向。

问题一:

“打开test.txt文件,发现文件末尾有个空格”。那是不是空格,不能用鼠标划拉一下就武断得出结论。如果一个文件中出现特殊字符(不能常规显示),那么应该用稍微专业一点的工具来判断它是什么字符。这对于程序员调试问题很重要,比如:

       $ cat -A file.txt  This is test^@     

注意后面是没有换行的,因为写的程序就是:

       char str[] = "This is test"; fwrite(str, 1, sizeof(str), fp);     

写入的就是"This is test",fwrite不会帮你加 或 等,所以这是一个没有换行的内容,也就不涉及 的问题。

然后再说结尾的那个所谓的“空格”是什么。用稍微专业一点的工具把文件内容显示出来,如:

       $ od -c file.txt  0000000   T   h   i   s       i   s       t   e   s   t   0000015     

就会看到文件的结尾实际上多了一个''。所以所谓的“空格”其实是这个''。至于为什么会有这个'',请仔细想想sizeof(str)是多少吧,换成strlen(str)再试试。

问题二:

“在windows上该如何正确使用fwrite()函数,才能让生成的文本文件在linux上打开读取也格式正确呢?”

fwrite只是单纯的让它写什么字符,它就写什么字符。如果要让一行的结尾是 ,就是写"This is test ",如果想让结尾是 ,就写"This is test "。

比如:

       #include <stdio.h> #include <string.h>  int main() {         char str[] = "This is test
";         FILE* fp;          fp = fopen("file.txt", "wb");         fwrite(str, 1, strlen(str), fp);         fclose(fp);          return(0); }     

编译执行就会得到:

       $ od -c file.txt  0000000   T   h   i   s       i   s       t   e   s   t  
 0000015     

结尾是 。比如修改为:

       ...         char str[] = "This is test
"; ...     

编译执行后就会得到:

       $ od -c file.txt  0000000   T   h   i   s       i   s       t   e   s   t  
  
 0000016     

结尾就是 。根本没有什么在windows上“正确使用fwrite()函数”的特殊做法,也就不存在问题中的要“解决windows上用fwrite向文件写入内容时结尾的 问题”。因为本来问题中的程序也没写 ,其次fwrite写不写 完全看你自己写没写。

补充说明:

(感谢@恨铁不成钢琴 指出上面程序fopen时未使用"b"参数时的问题,为了表述明确些,我做了如下补充说明)

注意上面的程序在fopen的时候使用了"wb"的参数,"b"这个参数在Windows系统下是有意义的:

       b Open in binary (untranslated) mode; translations involving carriage-return and line feed characters are suppressed.     

表示不要以translated模式打开文件,translated模式(也叫text模式),是windows为了让fopen标准函数的行为和其它系统一致而实现的。在fopen的posix标准中对它的定义没有明确的限制,参考下面链接:

所以Windows系统用这个参数来表示Binary mode,也就是untranslated mode。那么translate的什么呢?translate就是 和 。说直白了就是windows为了兼容自己 结尾和其它 结尾的系统的差异,默认(不使用b参数)的情况下会将 转换为 。比如上述程序如果写成:

       char str[] = "This is test
";  fp = fopen("file.txt", "w");     

也就是fopen时不使用"b"参数,那么这个程序在Linux上编译执行会写入"This is test ",在Windows上编译执行会写入"This is test "。这样这个程序可以在不修改的情况下达到在 结尾和 结尾的系统上都能写入正确的换行符号。

而如果写成:

       fp = fopen("file.txt", "wb");     

则对Linux系统没有影响,对Windows系统则让其不做 到 的转换。这样做也可以在保证不修改程序的情况下,让不同的系统都有一致的行为。

也就是说不使用b参数保证了文本换行时在不同系统的兼容性,使用b参数保证了程序行为在不同系统的一致性,所以是否使用"b"参数,程序员要根据自己程序的需要决定。

关于 和 在两个系统上兼容的问题:

说完这个问题本身的问题。最后我们回到Windows和Linux不兼容的 问题上来。

我们不知道提问者所要写的软件面向的是怎样的需求,如果需求是“在windows上写一个纯文本文件,然后Linux能正常读取,反之也是”。这个需求可以看成三个部分:

  1. 软件在Windows系统运行,可以用于读写纯文本格式的文件。
  2. 需要一种功能,让上述纯文本文件的内容在Linux和Windows格式间转换(如解决 问题)。
  3. 软件在Linux系统也正常运行,可以打开并阅读文件内容。
         Windows                           Linux +--------------+                  +-------------+ |              |   trans2Linux    |             | |  Read/Write  | ---------------> | Read/Write  | |  pure text   | <--------------- | pure text   | |  file        |   trans2Windows  | file        | |              |                  |             | +--------------+                  +-------------+     

那么功能部分就可以包括:

  1. 可以打开编辑纯文本文件的功能。
  2. 自动去除Windows和Linux间不兼容(如 和 )问题的功能。

而这个问题原始可能就是想问第二个,关于Windows和Linux间文件内容转换的问题。结果非要把一个问题A变成问题C来问,问成了如何让fwrite解决 和 不兼容的问题。结果就是问的人不明白,听的人也不明白到底要干嘛,不知道的以为你要改标准实现。

关于怎么做到兼容Windows和Linux文本格式的问题,其实是有实现的,比如Linux下的dos2unix软件:

比如我得到一个Windows下的文件:

       $ od -c dosfile  0000000   T   h   i   s   '   s       a       t   e   s   t  
  
   T 0000020   h   i   s   '   s       a       t   e   s   t       t   o   o 0000040  
  
   B   l   a   b   l   a   b   l   a   b   l   a  
  
 0000060     

可以看到每一行的结尾都是 ,那么我要把它转换为Linux可以正常查看的格式,可以执行:

       $ dos2unix -n dosfile unixfile dos2unix: converting file dosfile to file unixfile in Unix format...     

然后就可以看到:

       $ od -c unixfile  0000000   T   h   i   s   '   s       a       t   e   s   t  
   T   h 0000020   i   s   '   s       a       t   e   s   t       t   o   o  
 0000040   B   l   a   b   l   a   b   l   a   b   l   a  
 0000055     

每一行的结尾都变成了 。

当然除了 和 的差异以外,还可能存在很多别的差异。dos2unix工具都可以帮忙解决,并且还可以用于Mac系统。具体请查看dos2unix的文档,我就不详细介绍了。

即使不用dos2unix工具,你就是想把结尾的 都换成 来达到Linux兼容的目的,那一个简单粗暴的文本替换命令也是可以的,比如:

       $ sed 's/
$//' dosfile > unixfile2 $ od -c unixfile2 0000000   T   h   i   s   '   s       a       t   e   s   t  
   T   h 0000020   i   s   '   s       a       t   e   s   t       t   o   o  
 0000040   B   l   a   b   l   a   b   l   a   b   l   a  
 0000055     

怎么实现这个功能可以论证讨论,你也可以自己设计实现这样的功能,这不是问题的关键。问题的关键是你得能正常的分析需求,正常的拆解需求为合适的功能模块,合理的设计实现……这些才是一个程序员应该具备的。你不是甲方爸爸,你不能用一个乱成一团的需求把自己绕进去。只有甲方爸爸才可以提出这样的需求和问题:

而程序员首先要合理的拆分需求:

然后设计成一个个合理的独立的功能块:


user avatar   xing-ming-52-72 网友的相关建议: 
      

被各种朋友嘲笑订阅太低,比如跳舞:哥均订比你高订高,比如香蕉:我有四五万均订,七万高订,比如某表姐:日订阅破十一万人民币,比如三少:我每个月订阅都有好几十万呢,都是零花钱,比如奥斯卡:断更涨订阅,真的涨订阅……

感觉特别屈辱。

最屈辱的是经常有些新人跑过来,兴高采烈的说:蛤蟆哥哥,我均订破万了。你嫉妒的恨不得掐死他……




  

相关话题

  .net工作三年想转型做c++? 
  有哪些是当了程序员后才知道的事? 
  怎么看待程序员普遍缺乏数据结构和算法的知识? 
  为什么别选计算机专业? 
  如何理解互斥锁、条件锁、读写锁以及自旋锁? 
  用 vim 能写大型程序吗? 
  C/C++ 如何自定义printf函数的格式化符? 
  C语言中float的取值范围的问题,为啥? 
  C语言编译器哪个好用? 
  大学生为避免程序员中年被裁应当做哪些准备? 

前一个讨论
战斗机在遭到导弹追击时有没有可能通过耗尽导弹燃料而摆脱危机?
下一个讨论
男朋友是学医的,拒绝帮我按着伤口止血并表示绝不会碰正常吗?





© 2024-11-24 - tinynew.org. All Rights Reserved.
© 2024-11-24 - tinynew.org. 保留所有权利