前几天写类linux文件系统的时候,被这个搞死了,今天终于弄懂了
这是cpp文件
#include <iostream> #include <fstream> #include <stdio.h> #include <iomanip> using namespace std; char ch[250]; struct s{ short a, b; }; int main(){ FILE *file = fopen("test.txt", "wt+"); s st; st.a = 1, st.b = 2; fseek(file, 0, 0); fwrite(&st, sizeof(short), sizeof(st) / sizeof(short), file); //fseek(file, 0, 0); //fread(&st, sizeof(short), sizeof(st) / sizeof(short), file); char temp[256] = "flaf"; int c = 0x11110011; fseek(file, sizeof(st), 0); //加上这一句结果就不一样了 fprintf(file, "%s", temp); //fputs(temp, file); fwrite(&c, sizeof(int), 1, file); fseek(file, sizeof(st), 0); //fgets(temp, sizeof(temp), file); fscanf(file, "%s", temp); fread(&c, sizeof(int), 1, file); cout << temp <<" "<< c << endl; fclose(file); system("pause"); return 0; }
结果在读取字符串的时候,后面总是跟有乱码,而且整数c也总是有时读得对有时错,就像这样
这里有一个点很关键,可我一直都没意识到,字符串结束符\0其实在fprintf的时候是不会printf出来的,就像你在屏幕上看不到那个\0一样,fprintf只是把屏幕上的效果反映到文件里而已
而另一个点就是机器存储是大端序还是小端序的问题,我的CPU是Intel系列的,所以是小端序,即存储的时候低位在前,运行上面的那个程序,然后用HexEdit查看txt文件,将会是这样子
可以看到c = 0x11110011存储成了11 00 11 11,反过来了
所以这就是乱码的真相了:fscanf读取字符串的时候会一直读到 00 为止,所以上面输出的时候是flaf加一个乱码,后面的那个整数自然就成了无意义的数字了
要注意的是,如果换成fputs和fgets结果还是一样会乱码的,fputs、fgets和gets、puts的区别如下:
gets读取并丢弃换行符,puts会在最后添加换行符
fgets存储输入中的换行符,但相对应的,fputs并不会在最后添加换行符
最后还要注意的是:
如果在文件流中先读以后立即写,或者先写以后立即读,即不加上如fflush,fseek之类的操作,那么读(写)后面所有写(读)的操作都会失败
Over~
fprintf、fscanf读写乱码的问题,布布扣,bubuko.com
原文:http://blog.csdn.net/jiqiujia/article/details/19943727