目录
另外,假设成功打开了两个文件。补全下面函数调用中缺少的参数:
5.编写一个程序,接受两个命令行参数。第1个参数是字符,第2个参数是文件名。要求该程序只打印文件中包含给定字符的那些行。
C程序根据'\n'识别文件中的行。假设所有行都不超过256个字符,你可能会想到用fgets()
a.分别用fprintf()和fwrite()储存8238201有何区别?
b.分别用putc()和fwrite()储存字符S有何区别?
fprintf(stdout, "Hello, %s\n", name);
fprintf(stderr, "Hello, %s\n", name);
9."a+"、"r+"和"w+"模式打开的文件都是可读写的。哪种模式更适合用来更改文件中已有的内容?
1.修改程序清单13.1中的程序,要求提示用户输入文件名,并读取用户输入的信息,不使用命令行参数
2.编写一个文件拷贝程序,该程序通过命令行获取原始文件名和拷贝文件名。尽量使用标准I/O和二进制模式
4.编写一个程序,按顺序在屏幕上显示命令行中列出的所有文件。使用argc控制循环
5.修改程序清单13.5中的程序,用命令行界面代替交互式界面
6.使用命令行参数的程序依赖于用户的内存如何正确地使用它们。重写程序清单 13.2 中的程序,不使用命令行参数,而是提示用户输入所需信息。
7.编写一个程序打开两个文件。可以使用命令行参数或提示用户输入文件名。
a.该程序以这样的顺序打印:打印第1个文件的第1行,第2个文件的第1行,第1个文件的第2行,第2个文件的第2行,以此类推,打印到行数较多文件的最后一行。
9.修改程序清单 13.3 中的程序,从 1 开始,根据加入列表的顺序为每个单词编号。当程序下次运行时,确保新的单词编号接着上次的编号开始。
10.编写一个程序打开一个文本文件,通过交互方式获得文件名。通过一个循环,提示用户输入一个文件位置。然后该程序打印从该位置开始到下一个换行符之前的内容。用户输入负数或非数值字符可以结束输入循环。
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 5 8 8 8 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
复习题
1.下面的程序有什么问题
int main(void)
{
int * fp;
int k;
fp = fopen("gelatin");
for (k = 0; k < 30; k++)
fputs(fp, "Nanette eats gelatin.");
fclose("gelatin");
return 0;
}
#include <stdio.h>
int main(void)
{
FILE *fp;
int k;
fp = fopen("gelatin", "w");
for (k = 0; k < 30; k++)
fputs("Nanette eats gelatin.\n", fp);
fclose(fp);
return 0;
}
2.下面的程序完成什么任务?(假设在命令行环境中运行)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, char *argv [])
{
int ch;
FILE *fp;
if (argc < 2)
exit(EXIT_FAILURE);
if ((fp = fopen(argv[1], "r")) == NULL)
exit(EXIT_FAILURE);
while ((ch = getc(fp)) != EOF)
if (isdigit(ch))
putchar(ch);
fclose(fp);
return 0;
}
如果有第二个参数,尝试打开一个和该参数名同名的文件,如果该文件可以打开,在屏幕上输出一个其中的所有数字
3.假设程序中有下列语句:
#include <stdio.h>
FILE * fp1,* fp2;
char ch;
fp1 = fopen("terky", "r");
fp2 = fopen("jerky", "w");
另外,假设成功打开了两个文件。补全下面函数调用中缺少的参数:
a.ch = getc();
b.fprintf( ,"%c\n", );
c.putc( , );
d.fclose(); /* 关闭terky文件 */
a. fp1
b. fp2 ch
c. ch fp2
d. fp1
4.编写一个程序,不接受任何命令行参数或接受一个命令行参数。如果有一个参数,将其解释为文件名;如果没有参数,使用标准输入(stdin)作为输入。假设输入完全是浮点数。该程序要计算和报告输入数字的算术平均值
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void mktxt()
{
srand((unsigned long)time(0));
FILE *fp;
fp = fopen("321.txt", "w");
for (int j = 0; j < 100; ++j)
{
for (int i = 0; i < 7; ++i)
{
if(i == 3)
{
putc('.', fp);
}
putc(rand() % 10 + '0', fp);
}
putc('\n', fp);
}
fclose(fp);
}
int main(int argc, char** argv)
{
mktxt();
FILE *fp;
double n, sum = 0.0;
int num = 0;
if(argc == 1)
{
fp = stdin;
}
else if(argc == 2)
{
if((fp = fopen(argv[1], "r")) == NULL)
{
fprintf(stderr, "Open %s failed\n", argv[1]);
exit(EXIT_FAILURE);
}
}
else
{
fprintf(stderr, "Usage:%s [filename]\n", argv[0]);
exit(EXIT_FAILURE);
}
while(fscanf(fp, "%lf", &n) == 1)
{
num++;
sum += n;
}
if(num)
{
printf("%lf\n", sum / n);
}
else
{
puts("There is no number");
}
return 0;
}
5.编写一个程序,接受两个命令行参数。第1个参数是字符,第2个参数是文件名。要求该程序只打印文件中包含给定字符的那些行。
注意
C程序根据'\n'识别文件中的行。假设所有行都不超过256个字符,你可能会想到用fgets()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void mktxt()
{
srand((unsigned long)time(0));
FILE *fp;
fp = fopen("321.txt", "w");
for (int j = 0; j < 100; ++j)
{
int n = rand() % 256;
for (int i = 0; i < n; ++i)
{
putc(32 + rand() % 95, fp);
}
putc('\n', fp);
}
fclose(fp);
}
int main(int argc, char** argv)
{
mktxt();
FILE *fp;
char ch;
if(argc != 3)
{
fprintf(stderr, "Usage:%s [character] [filename]\n", argv[0]);
exit(EXIT_FAILURE);
}
else
{
if(strlen(argv[1]) != 1)
{
fprintf(stderr, "The second parameter should be a character\n");
exit(EXIT_FAILURE);
}
if((fp = fopen(argv[2], "r")) == NULL)
{
fprintf(stderr, "Open %s failed\n", argv[1]);
exit(EXIT_FAILURE);
}
}
ch = argv[1][0];
char a[256];
while(fgets(a, 256, fp) != NULL)
{
if(strchr(a, ch));
{
puts(a);
}
}
return 0;
}
6.二进制文件和文本文件有何区别?二进制流和文本流有何区别
这两种文件格式对系统的依赖性不同:二进制流和文本流的区别包括是在读写流时程序执行的转换(二进制流不转换,文本流可能要转换换行符和其他字符)
7.
a.分别用fprintf()和fwrite()储存8238201有何区别?
b.分别用putc()和fwrite()储存字符S有何区别?
a. 用fprintf()时把8238201当做7个字符存储,用fwrite()时把8238201当做一个4字节整形存储
b. 没有区别,都将其视为一个单字节二进制码
8.下面语句的区别是什么?
printf("Hello, %s\n", name);
fprintf(stdout, "Hello, %s\n", name);
fprintf(stderr, "Hello, %s\n", name);
第一句和第二句没有区别,第三条语句把消息写到标准错误上。
通常,标准错误被定向到与标准输出相同的位置。但标准错误不受标准输出重定向的影响
9."a+"、"r+"和"w+"模式打开的文件都是可读写的。哪种模式更适合用来更改文件中已有的内容?
r+
a+只允许在文件的末尾添加,w+会丢弃文件原有内容
编程题
1.修改程序清单13.1中的程序,要求提示用户输入文件名,并读取用户输入的信息,不使用命令行参数
#include <stdio.h>
#include <stdlib.h> // 提供 exit()的原型
int main()
{
int ch; // 读取文件时,储存每个字符的地方
FILE *fp; // “文件指针”
unsigned long count = 0;
char a[50];
printf("Input the filename:");
gets(a);
if ((fp = fopen(a, "r")) == NULL)
{
printf("Can't open %s\n", a);
exit(EXIT_FAILURE);
}
while ((ch = getc(fp)) != EOF)
{
putc(ch, stdout); // 与 putchar(ch);相同
count++;
}
fclose(fp);
printf("File %s has %lu characters\n", a, count);
return 0;
}
2.编写一个文件拷贝程序,该程序通过命令行获取原始文件名和拷贝文件名。尽量使用标准I/O和二进制模式
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void mktxt(char* a)
{
srand((unsigned long)time(0));
FILE *fp;
fp = fopen(a, "w");
for (int j = 0; j < 100; ++j)
{
int n = rand() % 256;
for (int i = 0; i < n; ++i)
{
putc(32 + rand() % 95, fp);
}
putc('\n', fp);
}
fclose(fp);
}
int main(int argc, char** argv)
{
mktxt(argv[1]);
FILE *fp1, *fp2;
if(argc != 3)
{
fprintf(stderr, "Usage:%s [filename] [filename]\n", argv[0]);
exit(EXIT_FAILURE);
}
else
{
if((fp1 = fopen(argv[1], "rb")) == NULL)
{
fprintf(stderr, "Open %s failed\n", argv[1]);
exit(EXIT_FAILURE);
}
if((fp2 = fopen(argv[2], "wb")) == NULL)
{
fprintf(stderr, "Open %s failed\n", argv[2]);
exit(EXIT_FAILURE);
}
}
char ch;
while((ch = getc(fp1)) != EOF)
{
putc(ch, fp2);
}
return 0;
}
3.编写一个文件拷贝程序,提示用户输入文本文件名,并以该文件名作为原始文件名和输出文件名。该程序要使用 ctype.h 中的 toupper()函数,在写入到输出文件时把所有文本转换成大写。使用标准I/O和文本模式
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
//在网上看好像C语言处理文本只能复制出来再读进去
void mktxt(char* a)
{
srand((unsigned long)time(0));
FILE *fp;
fp = fopen(a, "w");
for (int j = 0; j < 100; ++j)
{
int n = rand() % 256;
for (int i = 0; i < n; ++i)
{
putc(32 + rand() % 95, fp);
}
putc('\n', fp);
}
fclose(fp);
}
int main(int argc, char** argv)
{
mktxt(argv[1]);
FILE *fp1, *fp2;
if(argc != 2)
{
fprintf(stderr, "Usage:%s [filename]\n", argv[0]);
exit(EXIT_FAILURE);
}
else
{
if((fp1 = fopen(argv[1], "r")) == NULL)
{
fprintf(stderr, "Open %s failed\n", argv[1]);
exit(EXIT_FAILURE);
}
if((fp2 = fopen("midfile.txt", "w")) == NULL)
{
fprintf(stderr, "FAIL\n");
exit(EXIT_FAILURE);
}
}
char ch;
while((ch = getc(fp1)) != EOF)
{
if(islower(ch))
{
ch = toupper(ch);
}
putc(ch, fp2);
}
fclose(fp1);
fclose(fp2);
if((fp1 = fopen(argv[1], "w")) == NULL)
{
fprintf(stderr, "FAIL\n");
exit(EXIT_FAILURE);
}
if((fp2 = fopen("midfile.txt", "r")) == NULL)
{
fprintf(stderr, "FAIL\n");
exit(EXIT_FAILURE);
}
while((ch = getc(fp2)) != EOF)
{
putc(ch, fp1);
}
remove("midfile.txt");
return 0;
}
4.编写一个程序,按顺序在屏幕上显示命令行中列出的所有文件。使用argc控制循环
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
void mktxt(char* a)
{
srand((unsigned long)clock());
//用time()有个问题,因为只设置一次种子,每过两个文件文件内容就会重复,所以用clock
FILE *fp;
fp = fopen(a, "w");
for (int j = 0; j < 10; ++j)
{
int n = rand() % 256;
for (int i = 0; i < n; ++i)
{
putc(32 + rand() % 95, fp);
}
putc('\n', fp);
}
fclose(fp);
}
int main(int argc, char** argv)
{
FILE* fp;
char ch;
for (int i = 1; i < argc; ++i)
{
mktxt(argv[i]);
if((fp = fopen(argv[i], "r")) != NULL)
{
while((ch = getc(fp)) != EOF)
{
putchar(ch);
}
putchar('\n');
putchar('\n');
fclose(fp);
}
else
{
fprintf(stderr, "Open %s failed\n", argv[i]);
exit(EXIT_FAILURE);
}
}
return 0;
}
5.修改程序清单13.5中的程序,用命令行界面代替交互式界面
#include <stdio.h>
#include <stdlib.h>
#include <