C语言讲义——文件操作
fopen( ) 函数:创建一个新的文件或者打开一个已有的文件
FILE *fopen( const char * filename, const char * mode );
关于参数mode的取值
| r | 读 |
|---|---|
| w | 写(无文件则创建)(从头写) |
| a | 写(无文件则创建)(追加) |
| r+ | 读写 |
| w+ | 读写。如果文件存在,则截断为零长度,如果文件不存在,则创建一个新文件。 |
| a+ | 从头读,追加写(无文件则创建) |
| 读 | 写 | 新建 | 从头 | 追加 | |
|---|---|---|---|---|---|
| r | ○ | ○ | |||
| w | ○ | ○ | ○ | ||
| a | ○ | ○ | ○ | ||
| r+ | ○ | ○ | |||
| w+ | ○ | ○ | ○ | ○ | |
| a+ | ○ | ○ | ○ | ○ |
写文件示例
#include <stdio.h>
int fileWrite() {
FILE *fp = NULL;
fp = fopen("test.txt", "a+");
if(NULL == fp) {
// 将文件设为"只读",可测此处代码
puts("fopen出错");
// 使用perror()显示错误信息
perror("fopen() Err");
return -1;
}
fprintf(fp, "云想衣裳花想容,春风拂槛露华浓。\n");
fputs("若非群玉山头见,会向瑶台月下逢。\n", fp);
fclose(fp);
return 0;
}
main() {
fileWrite();
}
读文件示例
#include <stdio.h>
int fileRead() {
FILE *fp = NULL;
char buff[255];
fp = fopen("test.txt", "r");
if(NULL == fp) {
perror("fopen Error");
return -1;
}
fscanf(fp, "%s", buff);
printf("读取到空白字符: %s\n", buff );
fgets(buff, 255, (FILE*)fp);
printf("读取一行: %s\n", buff );
fclose(fp);
return 0;
}
main() {
fileRead();
}
偏移
fp = fopen(g_sFile, "r");
// int fseek(FILE *stream, long offset, int fromwhere);
// 第一个参数stream为文件指针
// 第二个参数offset为偏移量,整数表示正向偏移,负数表示负向偏移
// 第三个参数origin设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SET
// SEEK_SET:文件开头(0)
// SEEK_CUR:当前位置(1)
// SEEK_END:文件结尾(2)
// 定位成功:返回0
// 定位失败:返回非0
fseek(fp,1,SEEK_CUR);
示例:修改指定人员的成绩记录
现有成绩文件: data.dat
Apple,100;
Banana,098;
Cat,060;
Dog,032;
修改Cat的成绩为59分,即[Cat,060;]→[Cat,059;]前后内容都不变
为了方便定位,约定成绩都是3位字符表示
SEEK_CUR版
偏移数值问题——Unix和Windows不同
Unix(不算LF):fseek(fp, -4, SEEK_CUR)

Windows(算CR LF):fseek(fp, -6, SEEK_CUR)

SEEK_SET版
即使使用SEEK_SET从头找,找到上一行尾,再加,也有区别:
Unix:fseek(fp, nCurLen+4, SEEK_SET);
WIndows:fseek(fp, nCurLen+6, SEEK_SET);
结论:CRLF在内存中是不同的,所以fseek的参数有差别;但是反映在字符串上,都是一个\n(ASCII 10),比如第一行,strlen都是11
参考代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int updateFile() {
int nRet = 0;
FILE * fp = NULL;
fp = fopen("data.dat", "r+");// r+:读写
if (NULL == fp) {
perror("fopen() Err");
return 0;
}
// 读取文件
char buff[1024]= {0};
while(fgets(buff, 1024, fp)) {
// char *strstr(char *str1, const char *str2);
// 判断字符串str2是否是str1的子串。
// 是:返回str2在str1中首次出现的地址;
// 否:返回NULL
if(strstr(buff, "Cat") != NULL) {
//此时"光标"在读到的内容后面
int nSeek = fseek(fp, -6, SEEK_CUR);
if(nSeek != 0) {
perror("fseek");
break;
} else {
// 修改文件
fprintf(fp, "%s", "059");
nRet = 1;
break;
}
}
}
// 无果:关闭文件
fclose(fp);
return nRet;
}
int main(int argc, char *argv[]) {
updateFile();
return 0;
}
应用:读写log
#include <stdio.h>
#include <io.h>
#include <time.h>
#include <direct.h>
enum Level { DEBUG, INFO, WARING, ERROR};
const char* g_sDir = "temp";
const char* g_sFile = "temp/info.txt";
void getTime(char* sTime_o) {
time_t _time;
time(&_time);
struct tm *p =localtime(&_time);
// 格式化,并写入到字符串中
sprintf(sTime_o, "%d-%02d-%02d %02d:%02d:%02d",
p->tm_year+1900,
p->tm_mon + 1,
p->tm_mday,
p->tm_hour,
p->tm_min,
p->tm_sec);
}
int makeDir() {
// access:判断文件或文件夹是否存在
// <io.h>
// F_OK:判断是否存在
// success:0
// fault:-1
if (access(g_sDir, F_OK ) == 0) {
// 文件夹存在
} else {
// _mkdir:创建文件夹
// <direct.h>
// success:0
// fault:-1
if (_mkdir(g_sDir) == -1) {
printf("创建文件夹失败");
return -1;
}
}
return 0;
}
int logWrite(Level lvl, char*msg) {
// 获取时间
char sTime_o[200];
getTime(sTime_o);
//-------------------------
// 创建log文件夹
if(makeDir() == -1) {
return -1;
}
// 打开文件
FILE *fp = NULL;
fp = fopen(g_sFile, "a+");
if(NULL == fp) {
printf("无法打开文件%s\n", g_sFile);
return -1;
}
// 根据log级别,写入log
if (lvl == DEBUG) {
fprintf(fp, "%s [DEBUG] %s\n",sTime_o,msg);
} else if(lvl == INFO) {
fprintf(fp, "%s [INFO] %s\n",sTime_o,msg);
}
fclose(fp);
return 0;
}
int logRead() {
FILE *fp = NULL;
fp = fopen(g_sFile, "r");
if(NULL == fp) {
puts("文件读取失败");
return -1;
}
//TEST: 当前位置右移1
fseek(fp,1,SEEK_CUR);
// 读取文件
char buff[255] = {0};
while(fgets(buff, 255, (FILE*)fp)!=NULL) {
printf("> %s", buff );
}
fclose(fp);
return 0;
}
main() {
// 能写,才读;不写,不读
if (logWrite(INFO,"郭德纲") == 0) {
logRead();
}
}
C语言讲义——文件操作的更多相关文章
- C语言程序设计--文件操作
前言 这里尝试与Python对别的方法来学习C语言的文件操作,毕竟我是Pythoner. 文件打开与关闭 Python #因为是和C语言比对,所以不使用with filename = "/e ...
- C语言之文件操作08——总结
C程序的文件操作共涵盖7个例题,包括格式打印,文件读取,条件查找,矩阵的文件操作,数据格式输入及调用计算等内容. 文件操作使得程序有更强的拓展性,使其能够单独保存数据.这为程序的调试和优化打下了坚实的 ...
- C语言之文件操作
C语言之文件操作 在本节我们将会讲解有关文件的读写操作: 纲要: 一些需要掌握的知识点 文件名 文件类型 数据流 文件缓冲区 文件指针 与文件操作相关的一些函数 文件的打开及关闭 文件的顺序读写 文件 ...
- c语言_文件操作_FILE结构体解释_涉及对操作系统文件FCB操作的解释_
1. 文件和流的关系 C将每个文件简单地作为顺序字节流(如下图).每个文件用文件结束符结束,或者在特定字节数的地方结束,这个特定的字节数可以存储在系统维护的管理数据结构中.当打开文件时,就建立了和文件 ...
- c语言,文件操作总结
C语言文件操作 一.标准文件的读写 1.文件的打开 fopen() 文件的打开操作表示将给用户指定的文件在内存分配一个FILE结构区,并将该结构的指针返回给用户程序,以后用户程序就可用此FILE指针来 ...
- C语言的文件操作
在操作系统中,为了统一对各种硬件的操作,简化接口,不同的硬件设备也被看成一个文件.对于这些文件的操作,等于是对普通文件的操作.例如,通常把显示器称为标准输出文件,printf就是想这个文件输出,把键盘 ...
- C#语言-07.文件操作
a. 文件操作:适用于相对简单的数据保存 i. 读写文件的步骤: . 创建文件流 . 创建读写器 . 读写文件 . 关闭读写器 . 关闭文件流 ii. FileStream(文件流),它主要用于读写文 ...
- Linux下C语言的文件操作
代码: #include <stdio.h> #include <string.h> #include <fcntl.h> /*************基本的函数A ...
- 超赞的 Go 语言 INI 文件操作
灵活的数据源 不光光可以从文件读取配置,还支持 []byte 类型的纯数据读取和基于 io.ReadCloser 的流式读取. 多种格式兼容 各种文件种类的广泛支持,包括但不限于 my.cnf..gi ...
随机推荐
- kong in kubernetes
网关 这里提到的网关特指API网关.API网关是在微服务架构的演进过程中产生的,其核心功能是聚合后端服务,为客户端调用提供统一的门户.由于网关的集中式管理,在其上又衍生了限流.负载.路由管理.安全防护 ...
- [LuoguP1005]矩阵取数游戏 (DP+高精度)
题面 传送门:https://www.luogu.org/problemnew/show/P1005 Solution 我们可以先考虑贪心 我们每一次都选左右两边尽可能小的数,方便大的放在后面 听起来 ...
- ThreadLocal原理大解析
今天呢,和大家聊一下ThreadLocal. 1. 是什么? JDK1.2提供的的一个线程绑定变量的类. 他的思想就是:给每一个使用到这个资源的线程都克隆一份,实现了不同线程使用不同的资源,且该资源之 ...
- 微信小程序获取请求数据
<%@ WebHandler Language="C#" Class="CodeTest" %> using System; using Syste ...
- leetcode117search-in-rotated-sorted-array
题目描述 给出一个转动过的有序数组,你事先不知道该数组转动了多少 (例如,0 1 2 4 5 6 7可能变为4 5 6 7 0 1 2). 在数组中搜索给出的目标值,如果能在数组中找到,返回它的索引, ...
- python语言编程算法
编程题 1 台阶问题/斐波那契 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. fib = lambda n: n if n <= 2 else fi ...
- TRUNCATE 有约束的表
在有外键约束的情况下,truncate 表时,会报错, 我们可以设置外键检测为flase,执行完truncate命令后,再启用 SET foreign_key_checks = 0;TRUNCATE ...
- 【转】jps 命令使用
jps(Java Virtual Machine Process Status Tool)是JDK1.5提供的一个显示当前所有java进程pid的命令,简单实用,非常适合在linux/unix平台上简 ...
- Effective Modern C++ ——条款7 在创建对象时注意区分()和{}
杂项 在本条款的开头书中提到了两个细节性问题: 1.类中成员初始化的时候不能使用小括号. 如: class A { int a(0);//错误 }; 2.对于原子性类别的对象初始化的时候不能使用= 如 ...
- “”.length()与“”.split(",").length
public class test { public static void main(String[] args){ String str = ""; System.out.pr ...