chapter 8 文件
目录
C语言程序设计
chapter 8 文件
对于输入输出,一般我们分两种:
- 标准输入输出,也就是通过键盘和显示器控制台来输入输出。
- 文件输入输出,无需手动输入,程序会自动读写相关文件。
总的来讲文件操作形式有三种:
一、freopen文件重定向
二、fopen文件输入输出
三、fstream文件输入输出流
(部分竞赛不允许使用文件重定向,但是信息学竞赛专门考察文件重定向,可能是因为它更简单)。
1. freopen文件重定向
一、freopen文件重定向
需要使用freopen函数,包含于标准库 <stdio.h>中,使用格式如下:
freopen ( filename, mode, stream);
译:freopen ( 文件名, 文件打开模式, 文件流);
例:
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
//....
fclose(stdin); //关闭文件输入流
fclose(stdout); //关闭文件输出流
重定向样例
#include<stdio.h>
int main(){
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
int a,b,ans;
scanf("%d%d", &a, &b);
ans = a+b;
printf("%d", ans);
fclose(stdin);
fclose(stdout);
return 0;
}
2. fopen文件输入输出
二、fopen
需要使用fopen函数,包含于标准库 <cstdio>中,使用格式如下:
FILE *file = fopen( filename, mode);
译:FILE *file = fopen( 文件名, 文件打开模式);
例:
FILE *fin,*fout;
fin = fopen("data.in", "rb");
fout = fopen("data.out", "wb");
//注意:使用fopen的读写方式为文件读写 fscanf/fprintf
fclose(fin); //关闭文件
fclose(fout); //关闭文件
fopen改写为标准输入输出只需:fin=stdin; fout=stdout; 不需要fopen和fclose。
fopen样例
#include<stdio.h>
int main(){
FILE *fin, *fout;
fin = fopen("data.in", "rb");
fout = fopen("data.out", "wb");
int a,b,ans;
fscanf(fin, "%d%d", &a, &b);
ans = a+b;
fprintf(fout, "%d\n", ans);
fclose(fin);
fclose(fout);
return 0;
}
3. fopen标准输入输出
#include<stdio.h>
int main(){
FILE *fin, *fout;
fin = stdin;
fout = stdout;
int a,b,ans;
fscanf(fin, "%d%d", &a, &b);
ans = a+b;
fprintf(fout, "%d\n", ans);
//fclose(fin);//标准输入输出不需要fopen/fclose
//fclose(fout);
return 0;
}
4. fstream文件输入输出流
三、文件输入输出流
需要使用流操作以及设定输入输出对象到那个文件,二类的定义在标准库 <fstream>中,所以需要导入该头文件。
例:用fin作为输入对象,fout作为输出对象,可以使用如下定义:
ifstream fin("data.in"); //定义输入文件名
ofstream fout("data.out"); //定义输出文件名
fin.close(); //关闭文件
fout.close(); //关闭文件
文件输入输出流样例
#include<fstream>
using namespace std;
int main(){
ifstream fin("data.in");
ofstream fout("data.out");
int a,n,ans;
fin>>a>>b;
ans=a+b;
fout<<ans<<endl;
fin.close();
fout.close();
return 0;
}
5. scanf/printf and fscanf/fprintf and sscanf/sprintf
scanf/printf 表示从控制台输入输出
fscanf/fprintf 表示从文件输入输出
sscanf/sprintf 表示从字符串中输入输出(或者说赋值)给另外的字符串
当两者混用时,相互不影响,但是其作用都能表现出来。
#include<stdio.h>
int main(){
FILE *fin, *fout;
fin = fopen("data.in", "rb");
fout = fopen("data.out", "wb");
int a,b,ans;
fscanf(fin, "%d%d", &a, &b);
// scanf("%d%d", &a, &b);
ans = a+b;
fprintf(fout, "%d\n", ans);
printf("%d\n", ans);
fclose(fin);
fclose(fout);
return 0;
}
#include<stdio.h>
#include<string.h>
void fun1(){
char buf[100], buf2[100], buf3[100];
scanf("%s", buf);
sscanf(buf, "%s", buf2);//从 buf中以格式 %s 读入赋给 buf2
sprintf(buf3, "%s", buf2);//从 buf2中以格式 %s 读入赋给 buf3
printf(" buf=%s\n buf2=%s\n buf3=%s\n",buf, buf2, buf3);
}
void fun2(){
char ip[100]="192.168.1.1:8080", buf[100];
int a,b,c,d,e;
sscanf(ip, "%d.%d.%d.%d:%d", &a, &b, &c,&d, &e);
sprintf(buf, "%d.%d.%d.%d:%d", a, b, c,d, e);
printf("a=%d\n",a);
printf("b=%d\n",b);
printf("c=%d\n",c);
printf("d=%d\n",d);
printf("e=%d\n",e);
printf("strcmp(ip,buf)=%d\n", strcmp(ip,buf));
}
void fun3(){
char buf[]="`1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./";
printf("%d\n", strlen(buf));
for(int i=0; i<strlen(buf); i++){
printf("%c", buf[i]);
}printf("\n");
int a;
char buf2[100], buf3[100];
sscanf(buf, "%*c%d%s", &a, buf2);// *表示跳过
sprintf(buf3, "%d", a); //将 a的数据存入字符数组 buf3
printf(" a=%d\n buf2=%s\n buf3=%s\n", a, buf2, buf3);
}
int main(){
fun1();
fun2();
fun3();
return 0;
}
6. 头文件.h - 项目的形式
前面我们所学的都是通过单个页面书写程序,但是这样会使得程序主体过于复杂,
于是我们可以将部分关联性较强的程序封装另外一个文件中,在通过头文件导入的形式使用。
这样的形式在项目开发中更为常见,平时很少使用这样的习惯,但是我们也应当明白如何操作。
首先,我们要理解 头文件(head.h)的作用:封装一段具有完整功能的程序,可以直接调用。
头文件(head.h) 更接近于我们认识的函数声明,它更多的是告诉我们存在这个函数,并不做实现。
于是我们还需要一个对应的 函数方法实现文件 (head.c),用于将头文件中的函数声明进行实现。
举例:本次文件全部放在同一目录,如果是使用Dev-C++软件,需要选择项目创建的形式/ 如果是VSCode直接放在同一目录即可。
假设我们的头文件名为:lib
则 :( lib.h )文件下存放
#ifndef _LIB_H
#define _LIB_H
#define ll long long
ll fastpow(ll a, ll n, ll p); // a^n % p
ll halfpow(ll a, ll n, ll p); // a^n % p
#endif
(lib.c)文件下存放
#include "lib.h"
#define ll long long
ll fastpow(ll a, ll n, ll p){
ll ans=1;
while(n){
if(n&1) ans = ans*a%p;
a = a*a%p;
n >>= 1;
}
return ans;
}
ll halfpow(ll a, ll n, ll p){
if(n==0) return 1;
ll ans = halfpow(a, n/2, p);
ans = ans*ans%p;
if(n&1) ans = ans*a%p;
return ans;
}
主体程序,中存放
#include <stdio.h>
#include <windows.h>
#include "lib.h"
#include "lib.cpp" // vscode不是项目形式需要加上, Dev-C++项目形式不加
#define ll long long
int main(int argc, char** argv) {
ll a=2, n=10, p=1e7;
ll ans1 = fastpow(a, n, p);
ll ans2 = halfpow(a, n, p);
printf("ans1 = %lld\n", ans1);
printf("ans2 = %lld\n", ans2);
system("pause");
return 0;
}