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






<think>好的,我现在需要帮助用户解决如何在编程中打印特殊字符^@的问题。首先,我要回忆用户提到的具体需求,他们想知道如何在编程中打印这个特殊字符,尤其是在不同的编程语言中如何处理。用户还提到了引用[1]到[4]中的内容,这些引用提供了关于特殊字符处理的一些信息,比如转义序列的使用和Shell脚本中的处理方法。 首先,我要确定^@这个字符的具体含义。在ASCII码中,^@通常代表控制字符NUL,对应的ASCII码是0。这在不同的编程语言中可能有不同的处理方式,因为NUL字符通常用作字符串的终止符,尤其是在C语言中。因此,直接打印可能会有问题,需要特别处理。 接下来,我需要考虑不同编程语言中的方法。例如,在C语言中,使用printf打印NUL字符可能会遇到问题,因为字符串以\0结尾。所以可能需要用转义序列,比如\0或者使用ASCII码值来输出。不过要注意,直接打印\0会导致字符串终止,所以可能需要逐字符输出,或者使用其他函数如putchar。 对于Python,处理起来可能更简单,可以使用转义字符\0,或者在字符串中使用chr(0)来生成这个字符。但同样需要注意,某些环境或设备可能无法显示NUL字符,或者处理时会有异常。 然后,Shell脚本方面,用户引用[4]提到了使用tr命令来处理特殊字符,可能需要使用八进制转义,比如\000来表示ASCII 0。此外,echo命令可能需要-e选项来启用转义,但要注意不同Shell的兼容性问题,比如Bash和Dash之间的差异。 还要考虑用户可能遇到的常见问题,比如字符串被截断或者无法显示的问题,需要提供解决方案,比如逐字符输出或使用二进制模式写入文件。 最后,总结不同语言的方法,并提醒用户注意环境差异和潜在的问题,确保他们能够根据具体情况选择合适的方法。同时,生成相关的问题,帮助他们扩展知识,比如处理其他控制字符或在不同环境中打印特殊符号的方法。</think>在编程中打印特殊字符$^@$(ASCII码0,空字符)需要根据编程语言采用不同的转义方式。以下是具体实现方法及注意事项: ### 一、C语言实现 1. **转义序列法** 使用`\0`表示空字符,但需注意字符串会在此处终止: ```c printf("特殊字符: \0后续内容"); // 仅输出"特殊字符: " ``` 2. **ASCII码直接输出** 使用`putchar`函数逐字符输出: ```c putchar('^'); // 输出^ putchar('@'); // 输出@ putchar(0); // 输出空字符(可能无显示) ``` ### 二、Python实现 ```python # 方法1:转义字符 print("特殊字符: \x00") # 十六进制表示 # 方法2:chr函数 print(f"特殊字符: {chr(0)}") # 输出到文件避免截断 with open("output.bin", "wb") as f: f.write(b"^@\x00") ``` ### 三、Shell脚本实现 ```bash # 使用printf命令 printf "特殊字符: ^@\0\n" # 输出带空字符的字符串 # 八进制转义写法 echo -ne "特殊字符: ^@\000" > output.txt ``` ### 四、注意事项 1. **显示限制** 终端可能不显示ASCII码0-31的控制字符,建议通过`hexdump`验证: ```bash echo -ne "^@\0" | hexdump -C ``` 2. **文件操作** 写入文件时需使用二进制模式(如Python的`wb`模式),避免文本模式的自动转换[^2][^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值