vlambda博客
学习文章列表

C语言程序17:文件操作

C语言程序17:文件操作

Merry Christmas

C语言程序17:文件操作

文件操作




一、文件基本操作

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

/*

文件基本操作:

1.文件基础

文本文件

二进制文件

----------------------

stdin: 标准输入  ----->键盘-->外设

stdout: 标准你输出---->程序-->控制台窗口

stderr: 标准出错

自定义类型文件--->文件指针

流:数据流--->从一个地方移动到另一个地方

2.基本操作流程

2.1 定义文件指针

FILE *fp=NULL;

2.2 打开文件

FILE* fopen(char *fileURL,char *mode);

fileURL: 

相对路径-->相对于某一个文件,没有根目录

绝对路径-->可以根据目录找到相关文件

mode   :

w: write  写的方式 

r: read   读的方式

a: append 追加方式 

组合性质

b:二进制+:可读可写

wb,rb,ab,

wb+,w+

a+,ab+

细致区别:

w+: 文件不存在,能够创建文件 文件存在会清空文件

r+: 不存在创建功能 ,不存在清空功能

a+: 文件不存在,能够创建文件,在原文件末尾接着写

强调一点: 

<1>.读写方式一定要和操作一致,读写方式不对,读写操作一定错!

<2>.可以读写任何后缀结尾的!后缀是计算机文件的一种标识作用,重点在于改文件是如何读写的

2.3 读写文件

2.4 关闭文件

int fclose(FILE *fp);

文件打开失败,STREAM!=NULL

2.5 文件结束标记: EOF (-1) feof()

strcmp("str1","str2") >0

*/

//一般缓存文件如何做的

void readInfoToFile(char *fileName)

{

FILE *fp = fopen(fileName, "r");

if (fp == NULL)

{

fp = fopen(fileName, "w+");

}

fclose(fp);

}

int main()

{

FILE *fp = NULL;//1.定义文件指针

fp = fopen("write", "a+");

//防御性编程--->打开失败 返回NULL 

if (fp == NULL)

{

printf("文件打开失败!\n");

system("pause");

return 0;

}

fclose(fp);//关闭文件指针

system("pause");

return 0;

}





二、以字符和字符串的方式读写

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

/*

1.读写函数包含文件指针移动,在读写文件不需要自己去移动文件指针

2.以字符的方式读写

file putchar

file getchar

读:int fgetc(FILE* fp);

写:int fputc(char ch,FILE* fp);

3.以字符串的方式读写

读: char* fgets(char *str,FILE* fp)

写: int fputs(char *str,int count,FILE* fp);

//这个叫按行读写

*/


int main()

{

//字符的方式去写操作

char data[] = { "ILoveyou!" };

FILE *fp = fopen("write.txt", "w");

//string.h: strlen char * 等效C++cstring

//string:C++  类

//字符写

//for (int i = 0; i <= strlen(data); i++)

//{

//fputc(data[i], stdout);  //putchar();

//fputc(data[i], fp); 

//}

//字符串写

fputs(data, fp);

printf("\n");

fclose(fp);

//字符读写的弊端:大小问题

//字符读的方式

FILE *read = fopen("gets.txt", "r");

char readStr[2][1024] = {""};

//以字符的方式读

//int i = 0;

//while (!feof(read))

//{

//readStr[i++] = fgetc(read);

//}

//以字符串的去读

//多行文件读写

int count = 0;

while (!feof(read))

{

fgets(readStr[count], 1024, read);

printf("%s", readStr[count]);

count++;

}

printf("\n");

fclose(read);

system("pause");

return 0;

}





三、格式化读写(结构体方式读写文件)

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

struct MM

{

char name[20];

int age;

int num;

double score;

};

/*

//写操作

fprintf(FILE* file,char *str,....);

//读操作

fscanf(FILE* file,char *str,....);

除了指定一个file作为目的地,其他的和printf函数以及scanf函数一样的用法

fprintf(stdout, "%d\n%s\n", 1, "name1");

int num=0;

char name[20] = "";

fscanf(stdin, "%d%s", &num, name);

printf("%d\t%s\n", num, name);

//!格式读写不适用与文件指针移动函数


*/

int main()

{

/*  文件写操作

struct MM data[4] =

"name1", 18, 1001, 12.1,

"name2", 65, 1002, 13.1,

"name3", 25, 1003, 93.1,

"name4", 98, 1005, 19.0 

};

FILE *fp = fopen("MM.txt", "w");

for (int i = 0; i < 4; i++)

{

//宛如学习printf函数

fprintf(fp, "%s\t%d\t%d\t%.1lf\n", data[i].name, data[i].age, data[i].num, data[i].score);

}

fclose(fp);

*/

FILE *read = fopen("MM.txt", "r");

struct MM readData[4];

int count = 0;

int num;

//允许存在格式控制字符,不能存在精度调整

while (fscanf(read, "%s\t%d\t%d\t%lf\n", readData[count].name,

&readData[count].age, &readData[count].num, &readData[count].score) != EOF)

{

count++;

}

for (int i = 0; i < 4; i++)

{

printf("%s\t%d\t%d\t%.1lf\n", readData[i].name, readData[i].age, readData[i].num, readData[i].score); 

}

fclose(read);

system("pause");

return 0;

}





四、字符流的读写方式

#define _CRT_SECURE_NO_WARNINGS

#include <string.h>

#include <stdio.h>

#include <stdlib.h>

/*

fread(void *buf,size_t size,size_t,FILE *fp);

fwrite(void *buf,size_t size,size_t,FILE *fp);

写到文件中是乱码,是很正常的--->要注意的是只能能够读出来即可

*/


struct MM

{

char name[20];

int age;

int num;

double score;

};

int main()

{

//文件写操作

struct MM data[4] =

{

"name1", 18, 1001, 12.1,

"name2", 65, 1002, 13.1,

"name3", 25, 1003, 93.1,

"name4", 98, 1005, 19.0

};

FILE *fp = fopen("MM.txt", "wb");

//for (int i = 0; i < 4; i++)

//{

//fwrite(&data[i], sizeof(struct MM), 1, fp);

//}

//等效上面的循环

fwrite(data, sizeof(struct MM), 4, fp);

fclose(fp);

FILE *read = fopen("MM.txt", "rb");

struct MM readData[4];

//int count = 0;

fread(readData, sizeof(struct MM), 4, read);

for (int i = 0; i < 4; i++)

{

printf("%s\t%d\t%d\t%.1lf\n", readData[i].name, readData[i].age, readData[i].num, readData[i].score);

}

fclose(read);

system("pause");

return 0;

}





五、文件夹指针移动

#define _CRT_SECURE_NO_WARNINGS

#include <string.h>

#include <stdio.h>

#include <stdlib.h>

/*

操作文件转换:

1.int ftell(FILE *fp);文件移动多少位置--->fgets做动态内存申请

2.rewind(FILE *fp);文件指针移动开始位置

3.fseek(FILE* fp,long count,int mode);

count:移动多少个位置

正数:往前

负数:往后

mode:参照点

SEEK_SET 开始的位置

SEEK_END 结束的位置

SEEK_CUR 当前的位置

*/


struct MM

{

char name[20];

int age;

int num;

double score;

};

int main()

{

//文件写操作

struct MM data[4] =

{

"name1", 18, 1001, 12.1,

"name2", 65, 1002, 13.1,

"name3", 25, 1003, 93.1,

"name4", 98, 1005, 19.0

};

FILE *fp = fopen("MM.txt", "wb+");

fwrite(data, sizeof(struct MM), 4, fp);//文件指针到达文件末尾

printf("sizeof(MM):%d\n", sizeof(struct MM));

printf("size=:%d\n", ftell(fp));

struct MM readData[4];

//int count = 0;

rewind(fp);

fread(readData, sizeof(struct MM), 4, fp);

for (int i = 0; i < 4; i++)

{

printf("%s\t%d\t%d\t%.1lf\n", readData[i].name, readData[i].age, readData[i].num, readData[i].score);

}

//通过文件指针移动读取最后一个人的信息:

//当前位置,文件指针在文件末尾

printf("文件指针移动读取最后一个人的信息!:\n");

long size = sizeof(struct MM); //总共需要移动字节数

fseek(fp, -2 * size, SEEK_END); //往后移动,要写负数

struct MM tempData;

fread(&tempData, sizeof(struct MM), 1, fp);

printf("%s\t%d\t%d\t%.1lf\n", tempData.name, tempData.age, tempData.num, tempData.score);

fclose(fp);

system("pause");

return 0;

}





六、文件重定向

#define  _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

#include<stdlib.h>

/*

文件重定向:把程序所有输入和输出定向文件

当前程序是没有任何效果。

freopen(char *fileName,char *mode,FILE *file)



*/

int sum(int a, int b)

{

return a + b;

}

int main()

{

freopen("2.txt", "r", stdin);

int a = 0, b = 0;

scanf("%d%d", &a, &b);//从文件当中获取数据

freopen("1.txt", "w", stdout);

printf("sum=%d\n", sum(a, b));

return 0;

}






七、主函数参数

#include <stdio.h>

#include <stdlib.h>

int main(int argc,char*argv[])

{

//用到主函数参数的程序:一般称为命令行程序

//编译运行不了--->只有控制台输入指令

//argc: 指令个数

//copy 1.txt 2.txt   argc=3

//argv[0]: exe的目录 

//argv[1]: 1.txt

//argv[2]: 2.txt

if (argc != 3)

{

printf("USE 指令 file1 file2\n");

}

else

{   

printf("argv[0]:%s\n", argv[0]);

}

system("pause");

return 0;

}





八、mycopy

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

int main(int argc, char*argv[])

{

//用到主函数参数的程序:一般称为命令行程序

//编译运行不了--->只有控制台输入指令

//argc: 指令个数

//copy 1.txt 2.txt   argc=3

//argv[0]: exe的目录 

//argv[1]: 1.txt

//argv[2]: 2.txt

if (argc != 3)

{

printf("USE 指令 file1 file2\n");

}

else

{

FILE *file1 = fopen(argv[1], "r");

FILE *file2 = fopen(argv[2], "w");

if (file1 == NULL || file2 == NULL)

{

printf("系统找不到指定的文件。\n");

return 0;

}

printf("覆盖 %s 吗? (Yes/No/All):",argv[2]);

char userKey = getchar();

if (userKey == 'y' || userKey == 'Y')

{

int key = fgetc(file1);

while (key != EOF)

{

fputc(key, file2);

key = fgetc(file1);

}

printf("已复制         1 个文件。\n\n");

}

else

{

printf("已复制         0 个文件。\n\n");

}

fclose(file1);

fclose(file2);

}

return 0;

}


我知道你在看





新浪微博:@秀米XIUMI