1 文件重定向
文件重定向的程序
/* write_file.c -- 数据写入到文件 */
#include
int main(void)
{
int i;
char * pc;
const char *ptc[3] = { "hello c", "hello java", "hello python" };
for (i = 0; i < 3; i++)
{
pc = ptc[i];
while (*pc != '\0')
{
putchar(*(pc++));
}
putchar('\n');
}
return 0;
}
文件重定向
文件内容
2 文件是什么?
C语言把文件看作一系列连续的字节,每个字节都能被单独读取,这与UNIX环境中的文件结构相对应。C提供两种文件模式:文本模式和二进制模式。
3 标准文件
#include
#include /* 提供 exit() 函数原型 */
int main(int argc, char *argv[])
{
int ch; // 读取文件时,存储每个字符的地方
FILE *fp; // 文件指针
unsigned long int count = 0; // 文件字符计数
if (argc != 2)
{
printf("Usage %s filename\n", argv[0]); // exe路径
exit(EXIT_FAILURE);
}
if ((fp = fopen(argv[1], "r")) == NULL)
{
printf("Can't open %s\n", argv[1]); // 待读取文件路径
exit(EXIT_FAILURE);
}
while ((ch = getc(fp)) != EOF)
{
putc(ch, stdout); // 在屏幕上显示
count++;
}
fclose(fp);
printf("File %s has %lu characters.\n", argv[1], count);
return 0;
}
程序执行结果
程序分析
1 检查命令行参数
2 fopen() 函数
3 getc() 函数 putc() 函数 从文件中读取 / 写入字符
4 fclose() 函数
5 指向标准文件的指针
/* main.c -- 把文件压缩成原来的 1/3 */
#include
#include /* 提供 exit() 函数原型 */
#include /* 提供 strncpy() 函数原型 */
#define LEN 40
int main(int argc, char *argv[])
{
FILE *in, *out; /* 声明两个指向 FILE 的指针 */
int ch;
char name[LEN]; /* 存储输出文件名 */
int count = 0;
/* 检查命令行参数 */
if (argc < 2)
{
fprintf(stderr, "Usage %s filename\n", argv[0]);
exit(EXIT_FAILURE);
}
/* 设置输入 */
if ((in = fopen(argv[1], "r")) == NULL)
{
fprintf(stderr, "I couldn't open the file\" %s \"\n", argv[1]);
exit(EXIT_FAILURE);
}
/* 设置输出 */
strncpy(name, argv[1], LEN - 5); /* 拷贝文件名 */
name[LEN - 5] = '\0'; /* 字符串过长时,strcpy() 函数不拷贝 '\0' */
strcat(name, ".red"); /* 在文件名后面添加 .red */
if ((out = fopen(name, "w")) == NULL)
{
fprintf(stderr, "Can'create output file\n");
exit(EXIT_FAILURE);
}
/* 压缩拷贝数据 */
while ((ch = getc(in)) != EOF)
{
if (count++ % 3 == 0)
putc(ch, out); /* 向 out 文件中写入 1/3 的数据 */
}
/* 关闭文件 */
if (fclose(in) != 0 && fclose(out) != 0)
fprintf(stderr, "Error in closing files.\n");
return 0;
}
test.txt 的文件内容如下:
So even Eddy came oven reddy.
程序执行结果如下
生成的文件 test.txt.red
程序说明:
1 fprintf() 函数 fscanf() 函数
测试程序如下:
#include
#include
#include
#define MAX 41
int main(void)
{
FILE * fp;
char words[MAX];
if ((fp = fopen("wordy.txt", "a+")) == NULL)
{
fprintf(stderr, "Can't open \" wordy.txt \"\n");
exit(EXIT_FAILURE);
}
puts("Enter words to add to the file; press the #");
puts("key at the beginning of a line to terminate.");
/* 从键盘获取输入字符串,并输出到 fp 文件流 */
while ((fscanf(stdin, "%s", words)) == 1 && words[0] != '#')
fprintf(fp, "%s\n", words);
puts("File contents:");
rewind(fp); /* 返回到文件开始处 */
while (fscanf(fp, "%s", words) == 1)
puts(words);
puts("Done!");
if (fclose(fp) != 0)
fprintf(stderr, "Error closing file\n");
return 0;
}
程序执行结果(a+模式只允许在文件末尾添加内容,但可以读整个文件)
2 fgets() 函数和 fputs() 函数
倒序打印文件的程序
#include
#include
#define CTRL_Z '\032' /* DOS文本文件中的文件结尾标记 */
#define SLEN 81
char *s_gets(char *st, int n);
int main(void)
{
char file[SLEN];
int ch;
FILE * fp;
long int count, last;
puts("Enter the name of the file to be processed:");
/* 直接使用 fgets() 函数,会保留\n,导致打开文件失败 */
s_gets(file, SLEN);
if ((fp = fopen(file, "rb")) == NULL) /* 只读二进制模式 */
{
printf("Reverse can't open %s\n", file);
exit(EXIT_FAILURE);
}
fseek(fp, 0L, SEEK_END); /* 定位至文件末尾,偏移0 */
last = ftell(fp); /* 获取当前位置相对于文件首的偏移字节数 */
for (count = 1; count <= last; count++)
{
fseek(fp, -count, SEEK_END); /* 回退一字节 */
ch = getc(fp);
/* 为了兼容 MS-DOS,\r\n换行,Ctrl+Z 结束 */
if (ch != CTRL_Z && ch != '\r') /* MS-DOS文件 */
putchar(ch);
}
putchar('\n');
fclose(fp);
return 0;
}
/* 最多读取 n 字节的字符串,删除末尾的 \n,清空缓冲区 */
char *s_gets(char *st, int n)
{
int i = 0;
char *ret_val;
ret_val = fgets(st, n, stdin);
if (ret_val)
{
while (ret_val[i] != '\n' && ret_val[i] != '\0')
i++;
if (ret_val[i] == '\n')
ret_val[i] = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}
程序执行结果
1 fseek() 函数原理
2 程序的兼容性
1 ungetc() 函数 放回字符到输入流
2 fflush() 函数 刷新缓冲区
3 二进制IO函数
文本文件和二进制文件的区别
文本文件
二进制文件
关于 sprintf() 函数和 fwrite() 函数的区别
4 fwrite() 函数
5 fread() 函数
6 用二进制IO进行随机访问
#include
#include
#define ARSIZE 1000
int main(void)
{
double numbers[ARSIZE];
double value;
const char * file = "numbers.dat";
int i;
long pos;
FILE * fp;
/* 创建一组double类型的值 */
for (i = 0; i < ARSIZE; i++)
numbers[i] = i + 0.01;
/* 尝试打开文件 */
if ((fp = fopen(file, "wb")) == NULL) /* 二进制写入打开文件 */
{
fprintf(stderr, "Could not open %s for output.\n", file);
exit(EXIT_FAILURE);
}
/* 以二进制格式写入文件 */
fwrite(numbers, sizeof(double), ARSIZE, fp);
fclose(fp);
if ((fp = fopen(file, "rb")) == NULL) /* 二进制读取打开文件 */
{
fprintf(stderr, "Could not open %s for random access.\n", file);
exit(EXIT_FAILURE);
}
/* 从文件中读取选定的内容 */
printf("Enter an index in the range 0-%d.\n", ARSIZE - 1);
while (scanf("%d", &i) == 1 && i >= 0 && i < ARSIZE)
{
pos = i * sizeof(double);
fseek(fp, pos, SEEK_SET); /* 定位到文件偏移处 */
fread(&value, sizeof(double), 1, fp);
printf("The value there is %f.\n", value);
printf("Next index (out of range to quit) :\n");
}
fclose(fp);
puts("Done!");
return 0;
}
程序执行结果