linux TXT文件操作 '^@ ' 'NUL' 符号乱码问题

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

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

<span style="font-size:18px;">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分种数据】存入文件
}</span>


运行程序后 通过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下用记事本打开的 ,稍微做下处理就能达到预期的理想效果






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值