1.修改程序清单13.1中的程序,要求提示用户输入文件名,并读取用户输入的信息,不使用命令行参数。
#include
#include // 提供exit() 的原型
#define BUF 256
char *s_gets(char *st, int n);
int main(int argc, char *argv[])
{
int ch; // 读取文件时,存储每个字符的地方
FILE *fp; // "文件指针"
unsigned long count = 0;
char filename[BUF];
fprintf(stdout, "Input file name:");
if ( s_gets(filename, BUF) ) // 也可写个循环,这里为了测试才写if
{
if ( (fp = fopen(filename, "r")) == NULL )
{
printf("Can't open %s\n", filename);
exit(EXIT_FAILURE);
}
while ( (ch = getc(fp)) != EOF )
{
putc(ch, stdout); // 与putchar(ch);相同
count++;
}
putc('\n', stdout);
fclose(fp);
printf("File %s has %lu characters\n", filename, count);
}
return 0;
}
char *s_gets(char *st, int n)
{
char *ret_val;
ret_val = fgets(st, n, stdin);
if ( ret_val )
{
while ( *st != '\n' && *st != '\0' )
st++;
if ( *st == '\n' )
*st = '\0';
else
while ( getchar() != '\n' )
continue;
}
return ret_val;
}
/*
输出结果:
Input file name:Hello
Hello World!
File Hello has 12 characters
*/
2.编写一个文件拷贝程序,该程序通过命令行获取原始文件名和拷贝文件名。尽量使用标准I\O和二进制模式。
自行预先创建两个文件,在命令函中输入两个文件名即可拷贝
#include
#include
#include
#define BUF 4096 // 创建512字节倍数的buffer
void cype_file(FILE *source, FILE *dest); // 使用二进制模式的读/写函数进行拷贝
int main(int argc, char *argv[])
{
FILE *fs, *fa; // fs(源文件),fa(目标拷贝文件)
if ( argc != 3 )
{
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(EXIT_FAILURE);
}else if ( strcmp(argv[1], argv[2]) == 0 ) // 限定条件(无法拷贝自身)
{
fputs("Can't cype file to itself\n", stderr);
exit(EXIT_FAILURE);
}
if ( (fs = fopen(argv[1], "rb")) == NULL ) // 创建源文件
{
fprintf(stderr, "Can't open %s\n", argv[1]);
exit(EXIT_FAILURE);
}else if ( (fa = fopen(argv[2], "wb")) == NULL ) // 创建目标文件
{
fprintf(stderr, "Can't open %s\n", argv[2]);
exit(EXIT_FAILURE);
}else if ( setvbuf(fs, NULL, _IOFBF, BUF) != 0 ) // 创建源文件的完全缓冲区
{
fputs("Can't create output buffer\n", stderr);
exit(EXIT_FAILURE);
}else if ( setvbuf(fa, NULL, _IOFBF, BUF) != 0 ) // 创建目标文件的完全缓冲区
{
fputs("Can't create input buffer\n", stderr);
exit(EXIT_FAILURE);
}
cype_file(fs, fa); // 拷贝完成
fprintf(stdout, "Copy successfully!\n"); // 没有输出是因为,文件可能是二进制
fclose(fs);
fclose(fa);
return 0;
}
void cype_file(FILE *source, FILE *dest)
{
static char temp[BUF]; // 只分配一次
size_t bytes = 0L;
while ( (bytes = fread(temp, sizeof(char), BUF, source)) > 0 )
{
fwrite(temp, sizeof(char), bytes, dest);
}
}
3.编写一个文件拷贝程序,该程序通过用户输入文本文件名,并以该文件名和输出文件名。
#include
#include
#include
#include
#define BUF 512 // 创建512字节倍数的buffer
void cype_file(FILE *fp); // 使用二进制模式的读/写函数进行拷贝
int main(int argc, char *argv[])
{
FILE *fp;
char ch;
if ( argc != 2 )
{
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(EXIT_FAILURE);
}
if ( (fp = fopen(argv[1], "rb+")) == NULL ) // 创建源文件
{
fprintf(stderr, "Can't open %s\n", argv[1]);
exit(EXIT_FAILURE);
}else if ( setvbuf(fp, NULL, _IOFBF, BUF) != 0 ) // 创建文件输入/输出的完全缓冲区
{
fputs("Unable to create output/output buffer\n", stderr);
exit(EXIT_FAILURE);
}
cype_file(fp); // 拷贝完成
fputs("Done.\n", stdout);
fclose(fp);
return 0;
}
void cype_file(FILE *fp)
{
static char temp[BUF]; // 只分配一次
size_t bytes = 0L;
char *st;
while ( (bytes = fread(temp, sizeof(char), BUF, fp)) > 0 )
{
st = temp;
while ( *st )
{
*st = toupper(*st);
st++;
}
rewind(fp); // 返回到文件开始处
fwrite(temp, sizeof(char), bytes, fp);
}
}
/*
输出结果(以下结果使用测试代码得出的结果):
./Copy Hello
--------------------------测试【拷贝前】
HELLO WORLD!
--------------------------测试【拷贝后】
HELLO WORLD!
--------------------------
Done.
*/
4.编写一个程序,按顺序在屏幕上显示命令行中列出的所有文件。使用argc控制语句。
#include
#include
int main(int argc, char *argv[])
{
FILE *fp;
char ch;
int i;
if ( argc < 2 ) //限定条件
{
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(EXIT_FAILURE);
}
for ( i = 1; i < argc ; i++ )
{
if ( (fp = fopen(argv[i], "r")) == NULL ) //每次循环都打开一个文件
{
fprintf(stderr, "Can't open %s\n", argv[i]);
exit(EXIT_FAILURE);
}
fprintf(stdout, "File name %s: ",argv[i]); // 输出到屏幕
while ( (ch = getc(fp)) != EOF )
{
putc(ch, stdout);
}
putc('\n',stdout);
fclose(fp); // 关闭流
}
puts("Bye!");
return 0;
}
/*
输出结果:
./print_file Hello world
File name Hello: Hello
File name world: World!
Bye!
*/
5.修改程序清单13.5中的程序,用命令行界面代替交互界面。
/* append.c -- 把文件附加到另一个文件末尾 */
#include
#include
#include
#define BUFSIZE 4096
#define SLEN 81
void append(FILE *source, FILE *dest);
char *s_gets(char *st, int n);
int main(int argc, char const *argv[])
{
FILE *fa, *fs; // fa指向目标文件, fs指向源文件
int ch;
if ( argc != 3 ) // 限定条件
{
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(EXIT_FAILURE);
}else if ( strcmp(argv[1], argv[2]) == 0 )
{
fputs("Can't append file to itself\n", stderr);
exit(EXIT_FAILURE);
}
if ( (fa = fopen(argv[2], "a+")) == NULL ) // 打开目标文件
{
fprintf(stderr, "Can't open %s\n", argv[2]);
exit(EXIT_FAILURE);
}
if ( setvbuf(fa, NULL, _IOFBF, BUFSIZE) != 0 ) // 创建目标文件缓冲区4096字节大小
{
fputs("Can't create output buffer\n", stderr);
exit(EXIT_FAILURE);
}
if ( (fs = fopen(argv[1], "r")) == NULL ) // 打开源文件
{
fprintf(stderr, "Can't open %s.\n", argv[1]);
exit(EXIT_FAILURE);
}
if ( setvbuf(fs, NULL, _IOFBF, BUFSIZE) != 0 ) // 创建源文件缓冲区4096大小
{
fputs("Can't create input buffer\n", stderr);
}
append(fs, fa); // 拷贝源文件内容到目标文件
if ( ferror(fs) != 0 )
{
fprintf(stderr, "Error in reading file %s.\n", argv[1]);
}
if ( ferror(fa) != 0 )
{
fprintf(stderr, "Error in writing file %s.\n", argv[2]);
}
printf("File %s append.\n", argv[1]);
rewind(fa); // 将指针指向文件起始处
printf("%s contents:\n", argv[2]);
while ( (ch = getc(fa)) != EOF ) // 输出
{
putc(ch, stdout);
}
puts("\nDone displaying");
fclose(fa); // 关闭流
fclose(fs);
return 0;
}
void append(FILE *source, FILE *dest)
{
size_t bytes;
static char *temp[BUFSIZE]; // 只创建一次
while ( (bytes = fread(temp, sizeof(char), BUFSIZE, source)) > 0 )
{
fwrite(temp, sizeof(char), bytes, dest);
}
}
/*
输出结果:
./append world Hello
File world append.
Hello contents:
HelloWorld!
Done displaying
*/
6.使用命令行参数的程序依赖于用户的内存如何正确的使用它们。重写程序清单13.2中的程序,不使用命令行参数,而是提示用户输入所需的信息。
// reducto.c - 把文件压缩成原来的1/3!
#include
#include // 提供exit()的原型
#include // 提供 strcpy()、strcat()的原型
#define LEN 40
char *s_gets(char *st, int n);
int main(int argc, char const *argv[])
{
FILE *in, *out; // 声明两个指向 FILE 的指针
char source[LEN]; // source 源文件文件名
char dest[LEN]; // dest 目标文件文件名
int ch;
int count = 0;
printf("Enter the compressed file name:");
s_gets(source, LEN);
// 设置输入
if ( (in = fopen(source, "r")) == NULL )
{
fprintf(stderr, "can't open %s.\n", source);
exit(EXIT_FAILURE);
}
// 设置输出
strncpy(dest, source, LEN - 5); // 拷贝文件名;
dest[LEN - 5] = '\0'; // strncpy源字符可能大于最大限定个数时,将最后一个添为‘\0’
strcat(dest, ".red"); // 在文件名后添加.red
if ( (out = fopen(dest, "w+")) == NULL )
{
fprintf(stderr, "Can't create output file.\n");
exit(3);
}
//拷贝数据
while ( (ch = getc(in)) != EOF )
{
if ( count++ % 3 == 0 )
{
putc(ch, out); // 写3个字符中的第1个字符
}
}
// 收尾工作
if ( fclose(in) != 0 || fclose(out) != 0 )
{
fprintf(stderr, "Error in closing files\n");
}
puts("Done.");
return 0;
}
char *s_gets(char *st, int n)
{
char *ret_val;
ret_val = fgets(st, n , stdin);
if ( ret_val )
{
while ( *st != '\n' && *st != '\0' )
{
st++;
}
if ( *st == '\n' )
{
*st = '\0';
}else
{
while ( getchar() != '\n' )
{
continue;
}
}
}
return ret_val;
}
7.编写一个程序打开两个文件。可以使用命令行参数或提示用户输入文件名。
a
#include
#include
#define LEN 81
char *s_gets(char *st, int n);
int main(int argc, char const *argv[])
{
FILE *fp_one, *fp_two; // fp_one 指向第一个文件, fp_two指向第二个文件
char file_one[LEN]; // file_one第一个文件文件名
char file_two[LEN]; // file_two第二个文件文件名
char ch;
int mark_one = 1, mark_two = 1; // 标记,当读到文件末尾则置为0
printf("Enter the first file name:"); // 输入第一个文件名
s_gets(file_one, LEN);
if ( (fp_one = fopen(file_one, "r")) == NULL ) // 以读模式打开文件
{
fprintf(stderr, "Can't open %s.\n", file_one);
exit(EXIT_FAILURE);
}
printf("Enter the second file name:"); // 输入第二个文件名
s_gets(file_two, LEN);
if ( (fp_two = fopen(file_two, "r")) == NULL ) // 以读模式打开文件
{
fprintf(stderr, "Can't open %s.\n", file_two);
exit(EXIT_FAILURE);
}
do
{
if ( mark_one ) // 标记入口
{
while ( (ch = getc(fp_one)) != EOF ) // 从当前指针指向的数据开始读
{
putc(ch, stdout);
if ( ch == '\n' )
{
break; // 只要读取到换行符则退出循环
}
}
if ( ch == EOF ) // 当读取到EOF时换行,且关闭入口
{
putchar('\n');
mark_one = 0;
}
}
if ( mark_two ) // 标记入口
{
while ( (ch = getc(fp_two)) != EOF )
{
putc(ch, stdout);
if ( ch == '\n' ) // 只要读取到换行符则退出循环
{
break;
}
}
if ( ch == EOF ) // 当读取到EOF时换行,且关闭入口
{
putchar('\n');
mark_two = 0;
}
}
} while (mark_one || mark_two);
// 收尾工作
fclose(fp_one);
fclose(fp_two);
printf("Done!\n");
return 0;
}
char *s_gets(char *st, int n)
{
char *ret_val;
ret_val = fgets(st, n, stdin);
if ( ret_val )
{
while ( *st != '\n' && *st != '\0' )
{
st++;
}
if ( *st == '\n' )
{
*st = '\0';
}else
{
while (getchar() != '\n' )
{
continue;
}
}
}
return ret_val;
}
b
#include
#include
#define LEN 81
char *s_gets(char *st, int n);
int main(int argc, char const *argv[])
{
FILE *fp_one, *fp_two; // fp_one 指向第一个文件, fp_two指向第二个文件
char file_one[LEN]; // file_one第一个文件文件名
char file_two[LEN]; // file_two第二个文件文件名
char ch;
int mark_one = 1, mark_two = 1; // 标记,当读到文件末尾则置为0
printf("Enter the first file name:"); // 输入第一个文件名
s_gets(file_one, LEN);
if ( (fp_one = fopen(file_one, "r")) == NULL ) // 以读模式打开文件
{
fprintf(stderr, "Can't open %s.\n", file_one);
exit(EXIT_FAILURE);
}
printf("Enter the second file name:"); // 输入第二个文件名
s_gets(file_two, LEN);
if ( (fp_two = fopen(file_two, "r")) == NULL ) // 以读模式打开文件
{
fprintf(stderr, "Can't open %s.\n", file_two);
exit(EXIT_FAILURE);
}
do
{
if ( mark_one ) // 标记入口
{
while ( (ch = getc(fp_one)) != EOF ) // 从当前指针指向的数据开始读
{
if ( ch == '\n' && mark_two != 0 ) // 读取到换行符,如果第二个文件还没EOF则不输出\n
{
break;
}
putc(ch, stdout);
}
if ( ch == EOF ) // 当读取到EOF时换行,且关闭入口
{
if ( !mark_two ) // 当文件2还在的话,就不输出结束的\n
{
putchar('\n');
}
mark_one = 0;
}
}
if ( mark_two ) // 标记入口
{
while ( (ch = getc(fp_two)) != EOF )
{
putc(ch, stdout);
if ( ch == '\n' ) // 只要读取到换行符则退出循环
{
break;
}
}
if ( ch == EOF ) // 当读取到EOF时换行,且关闭入口
{
putchar('\n');
mark_two = 0;
}
}
} while (mark_one || mark_two);
// 收尾工作
fclose(fp_one);
fclose(fp_two);
printf("Done!\n");
return 0;
}
char *s_gets(char *st, int n)
{
char *ret_val;
ret_val = fgets(st, n, stdin);
if ( ret_val )
{
while ( *st != '\n' && *st != '\0' )
{
st++;
}
if ( *st == '\n' )
{
*st = '\0';
}else
{
while (getchar() != '\n' )
{
continue;
}
}
}
return ret_val;
}
8.编写一个程序,以一个字符和任意文件名作为命令行参数。如果字符后面没有参数,该程序读取标准输入;否则,程序依次打开每个文件并报告每个文件中该字符出现的次数。文件名和字符本身也要一同报告。程序应包含错误检查,以确定参数数量是否正确和是否能打开文件。如果无法打开文件,程序应报告这一情况,然后继续处理下一个文件。
#include
#include
#include
#define SLEN 20
char *s_gets(char *st, int n); // 标准输入获取文件名
void find_char(char *file_name, char c); // 打开文件及打印
int main(int argc, char *argv[])
{
char ch;
char file_name[20]; // 当参数只有一个字符时:使用标准输入获取filename
int i;
if ( argc < 2 || strlen(argv[1]) > 1 ) // 当参数小于2或者第一个参数不是字符时,结束
{
fprintf(stderr, "Usage: %s A character filename\n", argv[0]);
exit(EXIT_FAILURE);
}
ch = argv[1][0]; // 将第一个参数使用char类型保存
if ( argc == 2 ) // 如果只有一个参数时【标准输入】
{
printf("To stop, press the Enter key at a line's start.\n");
while ( s_gets(file_name, SLEN) && file_name[0] != '\0' )
{
find_char(file_name, ch);
printf("To stop, press the Enter key at a line's start.\n");
}
}else // 否则直接使用命令行参数的文件名
{
for ( i = 2; i < argc; i++ )
{
find_char(argv[i], ch);
}
}
puts("Done!");
return 0;
}
char *s_gets(char *st, int n)
{
char *find;
char *ret_val;
ret_val = fgets(st, n ,stdin);
if ( ret_val )
{
find = strchr(st, '\n');
if ( find )
{
*find = '\0';
}else
{
while ( getchar() != '\n' )
{
continue;
}
}
}
return ret_val;
}
void find_char(char *file_name, char c)
{
FILE *fp;
char temp;
int index = 0;
if ( (fp = fopen(file_name, "r")) == NULL )
{
fprintf(stderr, "Can't open %s\n", file_name);
return;
}
while ( (temp = getc(fp)) != EOF )
{
if ( temp == c )
{
index++;
}
}
printf("filename: %s ; character: %c ; index: %d\n", file_name, c, index);
fclose(fp);
}
/*
输出结果:
./find a Hello world
filename: Hello ; character: a ; index: 7
filename: world ; character: a ; index: 1
Done!
./find a
To stop, press the Enter key at a line's start.
Hello
filename: Hello ; character: a ; index: 7
To stop, press the Enter key at a line's start.
Done!
*/
9.修改程序清单13.3中的程序,从1开始,根据加入列表的顺序为每个单词编号。当程序下次运行时,确保新的单词编号接着上次的编号开始。
// 修改程序清单13.3中的程序,从1开始,根据加入列表的顺序为每个单词编号.
// 当程序下次运行时,确保新的单词编号接着上次的编号开始.
#include
#include
#define MAX 41
int main(void)
{
FILE * fp ;
char words[MAX] ;
int index = 0;
if ((fp = fopen("wordy" , "a+")) == NULL) // 创建一个存储单词的文件
{
fprintf(stderr , "Can't open \"wordy\" file.\n");
exit(EXIT_FAILURE);
}
//读出原数据
rewind(fp);
while ( fscanf(fp, "%d %s", &index, words) == 2 ); //从头开始读,最后index的值为最后编号的值
puts("Enter words to add to the file; press the #");
puts("key at the beginning of a line to terminate.");
while ((fscanf(stdin , "%40s" , words)) == 1 && (words[0] != '#'))
{
fprintf(fp , "%d %s\n" , ++index , words); //将编号自增后也写入文件内
}
puts("File contents:");
rewind(fp);
while ( fscanf(fp, "%d %s", &index, words) == 2 ) //固定格式输出
{
fprintf(stdout, "%d %s\n", index, words);
}
puts("Done!");
if (fclose(fp) != 0)
{
fprintf(stderr , "Error closing file.\n");
}
return 0 ;
}
/*
输出结果:
Enter words to add to the file; press the #
key at the beginning of a line to terminate.
Hello
world
#
File contents:
1 Hello
2 world
Done!
*/
10.编写一个程序打开一个文本文件,通过交互方式获取文件名。通过一个循环,提示用户输入一个文件位置。然后该程序打印从该位置到下一个换行符之前的内容。用户输入负数或非数值字符可以结束输入循环。
#include
#include
#define SLEN 40
char *s_gets(char *st, int n);
int main(void)
{
FILE *fp;
char file_name[SLEN];
long offset; // 偏移量
int ch;
printf("Enter file name:");
s_gets(file_name, SLEN);
if ( (fp = fopen(file_name, "r")) == NULL ) // 文件以读模式打开
{
fprintf(stderr, "Can't open %s file.", file_name);
exit(EXIT_FAILURE);
}
printf("Enter an integer:");
while ( scanf("%ld", &offset) == 1 && offset > 0 )
{
fseek(fp, offset, SEEK_SET); // SEEK_SET从文件起始处
while ( (ch = getc(fp)) != '\n' )
{
putc(ch, stdout);
}
putchar('\n');
printf("Enter an integer(q to quit):");
}
if (fclose(fp) != 0)
{
fprintf(stderr , "Error closing file.\n");
}
puts("Done!");
return 0;
}
char *s_gets(char *st, int n)
{
char *ret_val;
ret_val = fgets(st, n, stdin);
if ( ret_val )
{
while ( *st != '\n' && *st != '\0' )
{
st++;
}
if ( *st == '\n' )
{
*st = '\0';
}else
{
while ( getchar() != '\n' )
{
continue;
}
}
}
return ret_val;
}
11.编写一个程序,接受两个命令行参数。第一个参数是一个字符串,第2个参数是一个文件名。然后该程序查找该文件,打印文件中包含该字符串的所有行。因为该任务是面向行而不面向字符的,所以要使用fgets()而不是getc()。使用标准C库函数strstr()在每行中查找指定字符串。假设文件中的所有行都不超过255个字符。
#include
#include
#include // 提供strstr()原型
#define MAX 255
int main(int argc, char const *argv[])
{
FILE *fp;
char row[MAX]; // 将一行的数据存储到临时的数组中
if ( argc < 3 ) // 参数少于2个时结束
{
fprintf(stderr, "Usaga: %s Sring filename.\n", argv[0]);
exit(EXIT_FAILURE);
}
if ( (fp = fopen(argv[2], "r")) == NULL ) // 以读模式打开文件
{
fprintf(stderr, "Can't open %s file.\n", argv[2]);
exit(EXIT_FAILURE);
}
while ( 1 )
{
fgets(row, MAX, fp); // 读到最后一行时,它的文件指针并没有指向文件尾,而是指向’\r'处
if ( strstr(row, argv[1]) != NULL )
{
fputs(row, stdout);
}
if ( feof(fp) ) // 当文件读到末尾,就不能再执行以下代码。
{
break;
}
}
putchar('\n');
if ( fclose(fp) != 0 )
{
fprintf(stderr, "Error closing file.\n");
exit(EXIT_FAILURE);
}
puts("Done!");
return 0;
}
12.创建一个文本文件,内含20行,每行30个整数。这些整数都在0~9之间,用空格分开。该文件使用数字表示一张图片,0-9表示逐渐添加的灰度。
0 0 9 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 2 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 9 0 0 0 0 0 0 0 5 8 9 9 8 5 5 2 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 1 9 8 5 4 5 2 0 0 0 0 0 0 0 0 0
0 0 0 0 9 0 0 0 0 0 0 0 5 8 9 9 8 5 0 4 5 2 0 0 0 0 0 0 0 0
0 0 9 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 4 5 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 1 8 5 0 0 0 4 5 2 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 4 5 2 0 0 0 0 0
5 5 5 5 5 5 5 5 5 5 5 5 5 8 9 9 8 5 5 5 5 5 5 5 5 5 5 5 5 5
8 8 8 8 8 8 8 8 8 8 8 8 5 8 9 9 8 5 8 8 8 8 8 8 8 8 8 8 8 8
9 9 9 9 0 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 3 9 9 9 9 9 9 9
8 8 8 8 8 8 8 8 8 8 8 8 5 8 9 9 8 9 9 8 5 8 8 8 8 8 8 8 8 8
5 5 5 5 5 5 5 5 5 5 5 5 5 8 9 9 8 5 5 5 5 5 5 5 5 5 5 5 5 5
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 6 6 0 0 0 0 0 0
0 0 0 0 2 2 0 0 0 0 0 0 5 8 9 9 8 5 0 0 5 6 0 0 6 5 0 0 0 0
0 0 0 0 3 3 0 0 0 0 0 0 5 8 9 9 8 5 0 5 6 1 1 1 1 6 5 0 0 0
0 0 0 0 4 4 0 0 0 0 0 0 5 8 9 9 8 5 0 0 5 6 0 0 6 5 0 0 0 0
0 0 0 0 5 5 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 6 6 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0
#include
#include
#define ROW 20
#define COLUMN 31
#define SLEN 10
// 以下参数为:文件指针,二维数组
void file_append(FILE *f, char (*st)[COLUMN]); //功能:将二维数组中的内容附加给文件末尾
void change(FILE *f, char (*st)[COLUMN]); //功能:将文件中的“数字字符”转换成“字符符号”
//使用命令行读取文件名【参数:文件名】
int main(int argc, char const *argv[])
{
FILE *fp;
char picture[ROW][COLUMN] = {0}; // 20X31的二维数组
if ( argc < 2 )
{
fprintf(stderr, "Usaga: %s", argv[0]);
exit(EXIT_FAILURE);
}
if ( (fp = fopen(argv[1], "rb+")) == NULL )
{
fprintf(stderr, "Can't open %s file.", argv[1]);
exit(EXIT_FAILURE);
}
change(fp, picture); // 将文本文件中的数字以“字符符号”打印
fprintf(fp, "\nOutput result:\n"); // 输出结果
file_append(fp, picture); // 附加
fclose(fp);
puts("Done!");
return 0;
}
void change(FILE *f, char (*st)[COLUMN])
{
char char_arr[SLEN] = { ' ', '.', '\'', ':', '~', '*', '=', '$','%','#' }; //用于存储符号字符
int i, j;
int ch;
for ( i = 0; i < ROW; i++ )
{
for ( j = 0; j < COLUMN - 1; j++ )
{
if ( fscanf(f, "%d", &ch) == 1 )
{
st[i][j] = char_arr[ch]; //数字对应着字符数组下标的符号
}
}
puts(st[i]);
if ( ch == EOF ) // 当ch提前到末尾时结束
{
break;
}
}
}
void file_append(FILE *f, char (*st)[COLUMN])
{
int i;
for ( i = 0; i < ROW; i++ )
{
fwrite(st[i], sizeof(char), COLUMN - 1, f); // 将二维数组中的数据写到文件中
if ( i != ROW - 1 ) // 当到文件末尾时不换行
{
putc('\n', f);
}
}
}
13.用可变长数组(VAL)代替标准数组,完成编程练习12。
#include
#include
#define SLEN 10
// 以下参数为:行个数,列个数,二维数组, 文件指针
void file_append(int rows, int cols, char ar_VAL[rows][cols],FILE *f);//功能:将二维数组中的内容附加给文件末尾
void change(int rows, int cols, char ar_VAL[rows][cols],FILE *f);//功能:将文件中的“数字字符”转换成“字符符号”
int main(int argc, char const *argv[])
{
FILE *fp;
int row = 20;
int column = 31;
char picture[row][column]; // 20X31的二维数组的可变长数组
if ( argc < 2 )
{
fprintf(stderr, "Usaga: %s", argv[0]);
exit(EXIT_FAILURE);
}
if ( (fp = fopen(argv[1], "rb+")) == NULL )
{
fprintf(stderr, "Can't open %s file.", argv[1]);
exit(EXIT_FAILURE);
}
change(row, column, picture, fp); // 将文本文件中的数字以“字符符号”打印
fprintf(fp, "\nOutput result:\n"); // 输出结果
file_append(row, column, picture, fp); // 附加
fclose(fp);
puts("Done!");
return 0;
}
void change(int rows, int cols, char ar_VAL[rows][cols],FILE *f)
{
char char_arr[SLEN] = { ' ', '.', '\'', ':', '~', '*', '=', '$','%','#' }; //用于存储符号字符
int i, j;
int ch;
for ( i = 0; i < rows; i++ )
{
for ( j = 0; j < cols - 1; j++ )
{
if ( fscanf(f, "%d", &ch) == 1 )
{
ar_VAL[i][j] = char_arr[ch]; //数字对应着字符数组下标的符号
}
}
puts(ar_VAL[i]);
if ( ch == EOF ) // 当ch提前到末尾时结束
{
break;
}
}
}
void file_append(int rows, int cols, char ar_VAL[rows][cols],FILE *f)
{
int i;
for ( i = 0; i < rows; i++ )
{
fwrite(ar_VAL[i], sizeof(char), cols - 1, f); // 将二维数组中的数据写到文件中
if ( i != rows - 1 ) // 当到文件末尾时不换行
{
putc('\n', f);
}
}
}