一、对输入输出的理解
1.明确输入的意义
以往的输入为默认形式(标准输入流——stdin——键盘)。但是输入的形式不止此一种。可以从键盘上敲出输入的数据,同时也可以将文件中、某个字符串甚至结构体的数据作为输入内容进行输入。
输入,即为从某个地方获取数据。如各种get家族、各种scanf家族、以及fwrite,均是选择一个数据来源,获取该来源的数据。
2.明确输出的意义
同输入一样,以往的输出也为默认形式(标准输出流——stdout——屏幕)。输出的形式也不止此一种。可以在屏幕上显示输出的内容,同时也可以以文件、某个字符串等作为输出的位置,将内容输出至该位置。
输出,即为将内容呈现在某个地方。如put家族、printf家族、fread,均为将获取的内容,输出到一个选择好的地方。
3.输入输出的区分
如果在操作数据的时候,总是感觉输入输出傻傻分不清,那我想应该是没有把握住输入输出的核心要义,输入输出实际上是读或者写的一个过程。
当需要编辑一个文件、字符串等的内容时,实际上是需要将已有内容放入其中,逻辑很明显是选择一个地方来呈现内容,所以需要输出函数帮助;
当需要使用一个文件等的内容时,实际上是需要获取其中的内容,很明显属于输入函数的范畴。
二、输入输出函数辨析
这样打眼一看,感觉输入输出函数好多呀,怎么能区分的清楚呢?其实不难发现,这些函数基本主体就是put/get 和 printf/scanf,另外加了个前缀或后缀。
1.put/get <=> printf/scanf
这两组函数区别在于是否为格式化输出输入,从参数可以发现put/get组合不考虑内容的格式,而printf/scanf需要规定格式化的输入输出。
2.[printf/scanf] 无前缀 <=> f-前缀 <=> s-前缀
在我看来,前缀的主要作用就是说明该函数的输入输出流。
无前缀是针对标准输出输出流,即只能通过键盘屏幕来输入输出。
f-前缀是针对文件的输入输出流,传参传递文件指针即可。
s-前缀是针对字符串的输入输出流,传参传递字符串地址即可。
3.[put/get] f-前缀 <=> -s后缀 <=> -c后缀 <=> -char后缀
f-前缀是针对文件的输入输出流,需要额外传递文件指针。
-s后缀函数作用于操作内容为字符串的情况。
-c和-char后缀函数作用于操作内容为字符的情况。
4.补充说明
要对“流”有一个正确的认识,尽管专门用于文件操作的函数具有 FILE* stream 这样一个参数,但是我们要明白我们平时所使用的输入输出流只不过将这个参数默认为了stdin/stdout 而已,所以如果在文件操作函数的流参数处传递标准输入输出流,即可达成与常规的输入输出流相同的作用。
三、其他输入输出函数
二进制文件读写——fread/fwrite
第一个参数指输入内容指针,第二个参数指输入内容大小,第三个参数指输入个数,第四个指输入流(函数限制输入流只能是文件,所以此处应为文件指针)。
第一个参数指作为存储输出流内容的地址,第二个参数指输出内容的大小,第三个参数指输出内容的个数,第四个参数指输出流(也只能为文件指针)。
struct S
{
char name[20];
int age;
doubel score;
};
int main()
{
struct S s = {"张三",20,55.6};
struct S tmp = {0};
FILE* pf = fopen("test.txt","wb"};
if(pf==NULL)
{
return 0;
}
//二进制的形式写文件
fwrite(&s,szieof(struct S),1,pf);
//二进制的形式读文件
fread(&tmp,sizeof(struct S),1,pf);
printf("%s %d %lf\n",tmp.name,tmp.age;tmp.score);
fclose(pf);
pf = NULL;
return 0;
}
注:随机读写放在了另一篇博客内,需要的朋友可以自行浏览。