博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux TXT文件操作 '^@ ' 'NUL' 符号乱码问题
阅读量:2441 次
发布时间:2019-05-10

本文共 2481 字,大约阅读时间需要 8 分钟。

项目需求需要向TXT文件中写分钟数据, 也就是一分钟写一次, 一次一帧数据 ,一帧数据一行。

下面简单的贴下自己测试时的代码,  AWS_MIN1_DATA是一分钟数据结构体 (memset(&AWS_MIN1_DATA,1,sizeof(AWS_MIN1_DATA));),STID是结构体里面的一个数组成员。

void STORE_MIN1_DATA(struct tm *t){	int fd;	int ret;	//struct _AWS_MIN1_DATA AWS_MIN1_DATA;	AWS_MIN1_DATA.STID[0] = '1';	AWS_MIN1_DATA.STID[1] = '2';	AWS_MIN1_DATA.STID[2] = '3';	AWS_MIN1_DATA.STID[3] = '4';	AWS_MIN1_DATA.STID[4] = '5';		fd = open("/media/mmcblk0p1/test.txt", O_RDWR|O_APPEND|O_CREAT,777);			ret = write(fd,&AWS_MIN1_DATA,sizeof(AWS_MIN1_DATA));		printf("%d bytes have written!\n", ret);	lseek(fd,0,SEEK_END);	write(fd, "love", 4);	lseek(fd,0,SEEK_END);	write(fd,"\n", 2);	close(fd);	    //将【1分种数据】存入共享内存    //......................    //将【1分种数据】存入文件}

运行程序后 通过Linux的终端vi 打开test.txt文件显示

TXT文档是ASC码显示的 那个love在行尾,这里显示不出来. 其实后边还会多一个NUL字符.因为多写了个“love”字符串,而字符串会默认以'\0'结尾,而在C中

’\0‘是一个ASCII码为0的字符,为“空操作字符”,不引起控制动作,也不是一个可以显示的字符。

下面是在windows下用TXT打开后的结果 乱码了

网上查了下资料很快轻松找到问题所在:脱字符表示法

0x00 对应 ^@ (0+64)

至于TXT乱码的原因:Linux和Unix系统的换行是"\n",而Windows的换行并不是直接的"n",是"\r\n"。out.write("\n")只能得到一个黑框,因为Windows不认为这是个“换行”。 直接从记事本输入的话,Windows自动输入了"\r\n",所以从从文本文件中读出来的也是"\r\n",可以正常显示。那么这是为什么呢?稍微学过正则表达式的朋友都知道:\r是回车符,而\n是换行符。Windows默认\n在文档中显示的是一个空格或者小黑框。所以,要先回车,再换行。(此处引用百度回答

稍微改下代码

void STORE_MIN1_DATA(struct tm *t){	int fd;	int ret;	//struct _AWS_MIN1_DATA AWS_MIN1_DATA;	AWS_MIN1_DATA.STID[0] = '1';	AWS_MIN1_DATA.STID[1] = '2';	AWS_MIN1_DATA.STID[2] = '3';	AWS_MIN1_DATA.STID[3] = '4';	AWS_MIN1_DATA.STID[4] = '5';		fd = open("/media/mmcblk0p1/test.txt", O_RDWR|O_APPEND|O_CREAT,777);			ret = write(fd,&AWS_MIN1_DATA,sizeof(AWS_MIN1_DATA));		printf("%d bytes have written!\n", ret);	//lseek(fd,0,SEEK_END);	//write(fd, "love", 4);	lseek(fd,0,SEEK_END);	write(fd,"\r\n", 4);	close(fd);
//将【1分种数据】存入共享内存    //......................    //将【1分种数据】存入文件}

重新交叉编译程序,产生TXT文档在windows 下打开的截图

windows下打开TXT文档截图,行与行之间有空格是因为一帧数据太长 一行显示不完的缘故,除了开头的12345有显示之外,后边的都没显示是因为TXT文档是ASC字符显示(前边将结构体内的所有的数据都简单的初始化为1)

昨天搞错了, 上面记事本看到的是假象, 今天我又试了一下 ,拉伸一下记事本的边框, 就不是这样了,上面的是换行符/n 今天想了个特别的方法来解决这个问题

//if((t->tm_sec) == 0)//判断整分时间是否到	//{		//fd = open("/media/mmcblk0p1/test1.txt", O_RDWR|O_APPEND|O_CREAT,777);		fd = open("/media/mmcblk0p1/test1.txt", O_RDWR|O_CREAT,777);				lseek(fd,-2,SEEK_END);				ret = write(fd,&AWS_MIN1_DATA,sizeof(AWS_MIN1_DATA));				//lseek(fd,1,SEEK_END);		write(fd,"\r\n", 4);		lseek(fd,-2,SEEK_END);				close(fd);	//}
注意看一下区别,在打开文件时去掉了O_APPEND宏定义

每次写完之后重新定义写指针位置

下面是上面的代码运行效果截图:一个是在LINUX下用VI打开的 ,一个是在Windows下用记事本打开的 ,稍微做下处理就能达到预期的理想效果

你可能感兴趣的文章
“管家婆”软件用于维修管理 (转)
查看>>
第13章 术 语 大 全 (8) (转)
查看>>
第13章 术 语 大 全 (9) (转)
查看>>
人月神话读书笔记(二) (转)
查看>>
附录 UML元模 (转)
查看>>
A Brief Look at C++ 中文版 (转)
查看>>
JBuilder Editor中光标不能正确定位问题的解决 (转)
查看>>
XML加ASP实现网页“本地化” (转)
查看>>
Java中的异步网络编程 (转)
查看>>
用于核心模式驱动程序的网络体系结构(1) (转)
查看>>
More Effective C++ 条款20 (转)
查看>>
一个程序员的爱恋 (转)
查看>>
足球战术->边锋之Decorator篇 (转)
查看>>
编写优质无错代码(1) (转)
查看>>
MySQL 4.1.0 中文参考手册 --- 6.3 用于 SELECT 和 WHERE 子句的函数 (1) (转)
查看>>
vs.net beta 2中利用DataGrid分页详解 (转)
查看>>
Process-Display-Process (PDP) pattern (转)
查看>>
基于构件复用的软件方法与COM支持 (转)
查看>>
DELPHI中使用API函数详解 (转)
查看>>
Single Entry Point to EJB Layer (转)
查看>>