c 讲数据写入txt乱码_C课设学习笔记Day4-关于fwrite写入文件的乱码问题

news/2024/7/5 18:29:11

2f37b38f0c4ca3b6ce0ee560410e72f8.png
本文使用 Zhihu On VSCode 创作并发布

在笔记Day3最后的代码中,在使用fprintf和fwrite分别对文件进行写入操作时,发现了这样一个问题。

从键盘输入两个学生数据,先用fprintf()写入stu_list.txt文件中,再用fscanf()读出这两个学生的数据显示在屏幕上。然后再用 fwrite()写入 stu_list.dat 中,用 fread()读出这两个学生数据显示在屏幕上。
#include<stdio.h>
#include<stdlib.h>
struct stu{
	char name[10];
	int num;
};

int main(){
	FILE *fp;
	int i;
	struct stu a[2],b[2];
	if((fp=fopen("stu_info.txt","w+"))==NULL){    // 以读写方式打开文件"stu_info.txt" 
		printf("open error");
		getchar();
		exit(1);
	}
	//输入数据
	printf("ninput datan");
	for(i=0;i<2;i++){
		scanf("%s%d",a[i].name,&a[i].num);
	} 
	//输出数据到文件指针所指向文件
	for(i=0;i<2;i++){
		fprintf(fp,"%st%dn",a[i].name,a[i].num);
	} 
	//关闭文件,保证缓冲区的信息写入到文件中 
	fclose(fp);
	//再次以读写方式打开文件"stu_info.txt" 
	if((fp=fopen("stu_info.txt","r"))==NULL){    
		printf("open error");
		getchar();
		exit(1);
	}
	// 把文件内部位置指针移到文件首,用fscanf读出两个学生数据
	rewind(fp);
	for(i=0;i<2;i++){
		fscanf(fp,"%s%d",b[i].name,&b[i].num);
	}
    printf("nfprintf && fscanf ");
	printf("nnnametnumbern");
	for(i=0;i<2;i++){
		printf("%st%dn",b[i].name,b[i].num);
	}
	fclose(fp);	
	if((fp=fopen("stu_info.dat","w+"))==NULL){    
		printf("open error");
		getchar();
		exit(1);
	}
	// 用 fwrite()来写入文件
	fwrite(a,sizeof(struct stu),2,fp);	 
	fclose(fp);
	//再次以只读形式打开文件 
	if((fp=fopen("stu_info.dat","r"))==NULL){    
		printf("open error");
		getchar();
		exit(1);
	}
	rewind(fp);
	fread(b,sizeof(struct stu),2,fp);
    printf("nfwrite && fread ");
	printf("nnnametnumbern");   
	for(i=0;i<2;i++){
		printf("%st%dn",b[i].name,b[i].num);
	}
	fclose(fp);
	return 0;
} 

运行结果如图所示

1d86c256796b348d55ebebb3a16c7130.png
两种方式在程序中输出都是正常的

但是当我从硬盘中打开文件时,发现使用 fprintf 写入文件在记事本中的显示是正常的,而使用 fwrite 在文件中数字部分却变成了乱码而且并没有换行

8b36ce913502939d32e7c4d92b04f1b1.png
fprintf

b511cb171a0eb2053c0637d2e64a64f6.png
fwrite

那么,是什么原因造成了这种问题呢?

我在 C Primer Plus 中找到了这样一句话:

ANSI C 提供两种文件打开模式 :二进制和文本。以二进制打开文件时,可以逐字节读取文件;以文本模式打开文件时,会把文件内容从文本的系统表示法映射为 C 表示法。

ad0e369ef87402b165d18d529fe2e8f9.png
来自C Primer Plus的插图

众所周知,fprintf 写入文件时使用的是文本模式,fwrite 写入文件时使用的是二进制模式。

所以在存储一个数时(例如10001),fprintf 将其视为 5 个字符并保存在5个字节中(相当于将这个数拆分成 5 个单字符),每个单字符都能在 ASCii 表中找到对应的映射从而正确显示;
fwrite 则使用该数的二进制表示(相当于将这个数看成一个整体),并将其存储为一个4字节的整数,而这样的二进制数自然是无法被识别从而显示为乱码的。

而对于一个字符串,两者并没有差别,都是将该字符串储存为一个单字节的二进制码,所以两种函数输出的字符串在文件中都可以正确显示。

同时,二进制文件和文本文件格式对于系统的依赖性不同,在读写流时程序执行的转换支持也不同(二进制流不转换,而文本流需要转换换行符和其他功能字符)。因此在 fwrite 输出的文件中没有显示换行。



http://www.niftyadmin.cn/n/3040896.html

相关文章

Python自动化开发学习-爬虫1

讲师的博客&#xff1a;https://www.cnblogs.com/wupeiqi/articles/6283017.html 建立本地缓存 用下面的命令&#xff0c;就可以把一个页面爬取下来。不过再继续其他操作之前先把爬取的内容在本地建立缓存&#xff1a; import requests r requests.get(http://www.autohome.co…

ASP.NET 2.0 XML 系列(5):用XmlReader读取XML文档

一、使用XmlReader类的步骤如下 (1) 使用XmlReader类的Create()创建该类的一个实例&#xff0c;并将被读取的XML文件名称作为参数传入方法 (2) 建立一个反复调用的Read()方法的循环。这个方法从文件的第一个节点开始&#xff0c;然后读取所有余下的节点&#xff0c;但每次调用只…

mysql xml配置c_mysql主存配置

主要的事情写在前面: 主从配置文件主配置里面有一条 binlog-do-db&#xff1a;是指定mysql的binlog日志记录哪个数据库(库的名字)从配置里面有一条 eplicate-do-db:这个参数是在slave上配置&#xff0c;指定slave要复制哪个库所以上面两个一定要写上,才会成功.MySQL主从同步1. …

lighttpd配置实例

lighttpd异常自动重启脚本 1.建立脚本 vi /root/bin/check_lighttpd.sh #!/bin/bash datedate %Y-%m-%d-%H-%M if curl –head http://www.gaojinbo.com/index.html | grep "200" >/dev/null 2>&1 ; then echo lighttpd is ok $date >>/root/bin/c…

google proto buffer实战

使用与Thrift类似—— 下载EXE https://developers.google.com/protocol-buffers/docs/downloads Demo地址 https://developers.google.com/protocol-buffers/docs/javatutorial#compiling-your-protocol-buffers 中有addressbook.proto内容 举例子&#xff1a;放在 D:\Users\g…

sniper的中文翻译的pdf版本 BSD ROOTKIT 设计

sniper的中文翻译的pdf版本http://www.zif.cn/bsdrootkit.pdf转载于:https://blog.51cto.com/axlrose/1292982

PostgreSQL 10 build-in table partition(Range)

1.下载 rpm知识库包操作系统版本&#xff1a;CentOS Linux release 7.2.1511 (Core) X64[rootlocalhost home]# yum install https://download.postgresql.org/pub/repos/yum/testing/10/redhat/rhel-7-x86_64/pgdg-centos10-10-1.noarch.rpm Preparing... …

一次Mysql故障诊断过程

一次Mysql故障诊断过程<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />作者&#xff1a;田逸([email]sery163.com[/email]) from: [url]http://netsecurity.51cto.com/art/200803/67632.htm[/url]那天因参加MS的新品发布大会&a…