C语言_14 文件

简介: 文件;位运算初涉

13.1.1 格式化输入输出

从第一天学c语言就接触到了printf和scanf.下面彻底研究下占位符%d有多少细节。
printf: %[flags][width][.prec][hIL]type
flag:标志,有以下几种

flag 含义
- 左对齐(和width一起用)
+ 输出前面带正负号
(space) 正数留空
0 空格用0填充(不能和-同时使用)

width(宽度)或prec

width或prec 含义
number 最小字符数(包括小数点)
* 下一个读入的参数是字符数
.number 小数点后面的位数
.* 下一个参数是小数点后的位数

hIL:类型修饰符

类型修饰 含义
hh 单个字节
h short
l long
ll long long
L long double

type:类型

type 用于
i或d int
u unsigned int
o 八进制
x 十六进制
X 大写字母的十六进制
f或F float, 6
e或E 指数
g float
G float
a或A 十六进制浮点
c char
s 字符串
p 指针
n 读入/写出的个数

在这里插入图片描述
%n是当操作做到这里时,已经输出了多少个字符,并且填到指针所指的变量里。
scanf: %[flag]type

flag 含义
* 跳过
数字 最大字符数
hh char
h short
l long, double
ll long long
L long double
type 用于
d int
i 整数,可能是十六进制或八进制
u unsigned int
o 八进制
x 十六进制
a, e, f, g float
c char
s 字符串(单词)
[...] 所允许的字符
p 指针

%i会根据输入(如0x12、012)来判断是十六进制还是八进制还是十进制。
[...]举例
GPS中会读到一串字符,用逗号分隔
在这里插入图片描述
占位符%[^,]表示读入逗号前的所有字符
printf和scanf是有返回值的。scanf是返回几个item,即这次读入了几个变量;而printf则是这次输出了多少个字符。因此当我们面对要求严格的程序,比如长期运行的大程序,就需要判断每次调用scanf和printf的返回值来了解程序运行中是否会存在问题。

13.1.2 文件输入输出

我们之前运行程序的时候在命令行里输入./test(test是文件名)即可。
对文件做输入输出:./test > 12.out,然后再输入scanf标准输入的内容,但是程序没有printf标准输出了。但是打开12.out文件(输入more 12.out),会输出标准输入和标准输出。
同样,当我们输入 cat >12.in ,输入标准输入,然后再Ctrl D结束程序,再查看12.in文件(输入more 12.in)会输出标准输入。
然后运行test文件的时候这样写:./test < 12.in,12.in的内容会输入给./test,然后我们会得到其输出。
(当然还可以./test < 12.in > 12.out,输入是文件,输出也是文件。12.out里也有我们所期望的结果。)
以上是程序运行中的重定向。我们用<来指定一个文件的输入,用>来指定输出到一个文件中。
然而这并不是一般的文件输入输出方式,一般的方式需要做一个FILE,在stdlib.h中已经声明好过。
在这里插入图片描述
用fopen打开文件打开后用fscanf和fprintf函数来读写。

FILE* fp=fopen("file","r");//file是文件名,r表示读
if(fp){//如果没打开,会返回NULL
    fscanf(fp,...);//读文件。省略号的东西和正常的scanf一样了。后面还可以printf
    fclose(fp);
}else{}//无法打开的反馈。如:输出 无法打开文件

直接./test运行即可,会打开12.in然后正常输出。
如果删掉12.in(rm 12.in)就无法打开文件。
fopen第一个参数是文件名的字符串,第二个参数字符串用途如下:

r 打开只读
r+ 打开读写,从文件头开始读/写
w 打开只写,如果不存在则新建,如果存在则清空
w+ 打开读写,如果不存在则新建,如果存在则清空
a 打开追加,如果不存在则新建,如果存在不清空,从文件尾开始
在结尾加x 只新建,如果文件已存在则不能打开

13.1.3 二进制文件

所有文件最终都是二进制的。文本文件,只是用一种简单的方式可以进行读写的文件。如more, tail 可以打开文件,cat 打开文件或定向到其他文件,vi 做完整的编辑,etc。但是二进制没这么简单。
选择文本还是二进制?
UNIX(和windows一样都是操作系统。)喜欢用文本文件储存数据、配置程序。交互式终端的出现(类似windows的cmd窗口)使得人们喜欢用文本和计算机“交流”。因此,UNIX的shell就提供了一些读写文本的小程序。
windows(更准确要说DOS),个人计算机的制作者并不继承、熟悉UNIX文化(宛如在围墙之外,不熟悉围墙内)全凭自己的理解做出草根文化的DOS,更喜欢用二进制文件。
PC和DOS刚开始的时候能力有限,二进制更加接近底层。
文本、二进制各有优劣。
文本方便人类读写,而且跨平台;缺点是程序的输入输出要经过格式化,开销大。
二进制的缺点是人类读写困难而且不跨平台;(如不同计算机int大小不一致)优点是读写快。
在这里,我们要回顾下为什么程序要使用文件。

  1. 有配置(比如窗口大小、字体颜色)UNIX用文本文件就能编辑,Windows是用一个大文件:注册表编辑。
  2. 数据:保存数据,如学生成绩。稍微大一些的数据都放数据库那了。
  3. 媒体:如图片音频,这些不能是文本文件,只能是二进制文件。

其实现在程序通过第三方库来读写文件,很少直接读写二进制文件了。
对二进制的读写
在这里插入图片描述
第一个参数是指针,要读写的内存;第二个参数是那块内存(一个结构)的大小;第三个参数是有几个这样的内存,第四个参数是文件指针。返回成功读写的字节数。
因为二进制文件的读写一半是通过对一个结构变量的操作来进行的,所以nitem就是用来说明这次读写了几个结构变量。
这里老师做了一个非常有意思的东西,建议去看看(我懒了)
fwrite可以把数据以二进制形式写到文件中,fread类似。
定位:找出现在处在文件中的位置,或跳到指定位置。

long ftell(FILE *stream);
int fseek(FILE *stream, long offset, int whence);
/*whence:SEEK_SET 从头开始
SEEK_CUR 从当前位置开始
SEEK_END 从末尾开始*/

如:fseek(fp, 0L, SEEK_END);当前位置就在结尾了。这时如果我们令long size=ftell(fp);得到的就是文件大小。
我们可以先这样获得文件大小,然后除以sizeof来得知内部储存了多少个数据;然后用户说我想看第几个数据,我们再利用fseek函数跳到那个位置,输出每一项。
这样的二进制文件不具备可移植性;即在int为32位的机器上写出的数据文件不能在int为64位的机器上正确读出。解决方案1是放弃int,使用typedef具有明确大小的类型;2是用文本。

目录
相关文章
|
13天前
|
Linux C语言
C语言 文件IO (系统调用)
本文介绍了Linux系统调用中的文件I/O操作,包括文件描述符、`open`、`read`、`write`、`lseek`、`close`、`dup`、`dup2`等函数,以及如何获取文件属性信息(`stat`)、用户信息(`getpwuid`)和组信息(`getgrgid`)。此外还介绍了目录操作函数如`opendir`、`readdir`、`rewinddir`和`closedir`,并提供了相关示例代码。系统调用直接与内核交互,没有缓冲机制,效率相对较低,但实时性更高。
|
1月前
|
存储 C语言
【C语言】C语言-学生成绩管理系统(源码+数据文件+课程论文)【独一无二】
【C语言】C语言-学生成绩管理系统(源码+数据文件+课程论文)【独一无二】
37 15
|
1月前
|
存储 C语言
【c语言】职工信息管理系统 包含读取写入txt文件,职工信息的增删改查
【c语言】职工信息管理系统 包含读取写入txt文件,职工信息的增删改查
|
1月前
|
存储 自然语言处理 程序员
【C语言】文件的编译链接和预处理
【C语言】文件的编译链接和预处理
|
1月前
|
存储 C语言
【C语言】C语言-设备管理系统(源码+数据文件)【独一无二】
【C语言】C语言-设备管理系统(源码+数据文件)【独一无二】
|
2月前
|
Linux C语言 Windows
C语言文件编程-Linux环境下运行
本文介绍了在Linux环境下使用C语言进行文件编程时的两种主要接口:C标准库函数与Linux系统调用。C标准库提供了`fopen`, `fread`, `fwrite`, 和 `fclose`等函数,适用于普通文件操作;而Linux系统调用如`open`, `read`, `write`, 和 `close`则更适合处理设备文件,同时也可用于普通文件。这两种方法的主要区别在于前者使用文件指针,后者使用文件描述符。文章还给出了两个示例程序:一个使用C标准库函数实现文件复制,另一个则使用Linux系统调用完成相同任务。
30 2
|
3月前
|
编译器 C语言
C语言编译详解:GCC分步编译与一次编译多个文件
C语言编译详解:GCC分步编译与一次编译多个文件
227 2
|
3月前
|
存储 C语言
C语言文件读写详解
C语言文件读写详解
|
3月前
|
存储 编译器 数据库
【再识C进阶5(上)】详细介绍C语言文件操作——文件是用于存储数据
【再识C进阶5(上)】详细介绍C语言文件操作——文件是用于存储数据
|
3月前
|
Java 程序员 Linux
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
36 0