C读写文件
使用 fopen(文件名,访问模式) 函数来打开文件,一般有getc/putc , fgets/fputs , fscanf/fprintf , fread/fwrite 四大家族来读写文件。
关于文件访问模式有如下的选择:
访问模式 | 说明 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
1、getc/putc家族读写文件
int getc(FILE *stream) :从文件读取字符, 一次读取一个字符,并把位置标识符往前移动。
参数:指向 FILE 对象的指针
返回值:以 int 的形式返回读取的字符,如果到达文件末尾或发生读错误,则返回 EOF。
int putc(int c , FILE *stream):将指定的字符输出到指定的输出流中,并把位置标识符往前移动。
参数:c -- 要被写入的字符,该字符以其对应的 int 值进行传递。
stream -- 指向 FILE 对象的指针
返回值:以 int 的形式返回写入的字符,如果发生错误则返回 EOF
使用示例:
#include
//读一个字符
int main(int argc,char *argv[])
{
FILE *p = fopen("/Users/Devin/Desktop/a.txt", "r");
if (p == NULL)
{
printf("文件打开失败\n");
}
else
{
char c = 0;
while( (c = getc(p)) != EOF)//EOF代表文件最后的一个结束标示
{
printf("%c", c);
}
//使用完,关闭文件
fclose(p);
}
return 0;
}
//写一个字符
int main(int argc,char *argv[])
{
FILE *p = fopen("/Users/Devin/Desktop/a.txt", "w");
if (p == NULL)
{
printf("文件打开失败\n");
}
else
{
putc('a', p);
putc('b', p);
putc('c', p);
fclose(p);
}
return 0;
}
2、fgets/fputs家族读写文件
char *fgets(char *s, int size, FILE *stream); 按行读取,当读到文件尾时结束,返回NULL。
参数:s -- 这是指向一个字符数组的指针,该数组存储了要读取的字符串。
size -- 这块内存的大小,
stream -- fopen返回的文件指针
返回值:如果成功,该函数返回相同的 str 参数。如果为空或者错误返回空指针
int fputs(char *s, FILE *stream);按行写入。
参数:s -- 要写入的内容
stream -- fopen返回的文件指针
返回值:写入成功返回非0,写入失败返回EOF。
使用示例:
//读
int main(int argc,char *argv[])
{
FILE *p = fopen("/Users/Devin/Desktop/a.txt", "r");
if (p == NULL)
{
printf("文件打开失败\n");
}
else
{
char s[1024] = { 0 };
fgets(s, sizeof(s), p);
printf("%s",s);
fclose(p);
}
return 0;
}
//写
int main(int argc,char *argv[])
{
FILE *p = fopen("/Users/Devin/Desktop/a.txt", "w");
if (p == NULL)
{
printf("文件打开失败\n");
}
else
{
fputs("hello", p);
fclose(p);
}
return 0;
}
3、fscanf/fprintf家族读写文件
int fscanf(FILE *stream, const char *format, ...):fscanf与scanf用法基本一致,fscanf是从一个文件读取输 入,scanf是从键盘读取输入
参数:stream -- 指向 FILE 对象的指针
format -- 格式化输入
返回值:该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误,则返回 EOF。
int fprintf(FILE *stream, const char *format, ...)
返回值:返回写入的字符总数,否则返回一个负数。
使用示例:
//读
int main(void)
{
//文件内容为:1 + 2
FILE *p = fopen("/Users/Devin/Desktop/a.txt", "r");
while(!feof(p))
{
int a = 0;
int b = 0;
fscanf(p, "%d + %d", &a, &b);
printf("a = %d, b = %d\n", a, b);
//输出a = 1, b = 2
}
fclose(p);
return 0;
}
//写
int main()
{
FILE *p = fopen("/Users/Devin/Desktop/a.txt", "w");
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int i;
for(i = 0; i < 10; i++)
{
fprintf(p, "arr[%d] = %d\n", i, arr[i]);
}
fclose(p);
return 0;
}
4、fread/fwrite家族读写文件
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream):从文件流中读数据
参数:ptr -- 这是指向带有最小尺寸 size*nmemb 字节的内存块的指针。
**size** -- 这是要读取的每个元素的大小,以字节为单位。
nmemb -- 要读nmemb个数据项,每个数据项size个字节。
stream -- 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流。
返回值:成功读取的数据项总数
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream):向指定的文件中写入数据
参数:ptr -- 这是指向要被写入的元素数组的指针。
size -- 这是要被写入的每个元素的大小,以字节为单位。
nmemb -- 要读nmemb个数据项,每个数据项size个字节。
stream -- 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输出流。
返回值:成功写入的数据项总数
使用示例:
//写
int main(void)
{
struct student st = {"小明", 10};
FILE *p = fopen("/Users/Devin/Desktop/a.dat", "wb");
fwrite(&st, sizeof(st), 1, p);
fclose(p);
return 0;
}
//读
int main(void)
{
struct student st;
FILE *p = fopen("/Users/Devin/Desktop/a.dat", "rb");
fread(&st, sizeof(st), 1, p);
fclose(p);
printf("name = %s, age = %d\n", st.name, st.age);
return 0;
}