admin管理员组

文章数量:1534191

前言:

本篇为《维生素C语言》系列配套练习题,挑选了一些相对来说比较实用的练习,有助于巩固学习的知识。题目附带了答案和解析可供参考,顺便附上文件操作教学链接,可供复习:

【维生素C语言】第十六章 - 文件操作(上)本章为文件操作教学上篇,由浅入深的引入问题,然后逐一介绍知识。将详细讲解文件的打开和关闭、文件的顺序读写并精讲函数部分,初步学习“流”的概念!https://blog.csdn/weixin_50502862/article/details/119715195【维生素C语言】第十六章 - 文件操作(下)本章为文件操作教学下篇,将对文件的随机读写进行讲解,详细探讨上篇提到的文本文件和二进制文件。探究文件读取结束的判定、文件缓冲区等问题。https://blog.csdn/weixin_50502862/article/details/119807906


一、选择题

❓ C语言以二进制方式打开一个文件的方法是?

A. FILE *f = fwrite( "test.bin", "b" );

B. FILE *f = fopenb( "test.bin", "w" );

C. FILE *f = fopen( "test.bin", "wb" );

D. FILE *f = fwriteb( "test.bin" );

❓ 关于 fopen 函数说法不正确的是?

A.  fopen打开文件的方式是"r",如果文件不存在,则打开文件失败

B.  fopen打开文件的方式是"w",如果文件不存在,则创建该文件,打开成功

C.  fopen函数的返回值无需判断

D.  fopen打开的文件需要fclose来关闭

❓ 下列关于文件名及路径的说法中错误的是?

A.  文件名中有一些禁止使用的字符

B.  文件名中一定包含后缀名

C.  文件的后缀名决定了一个文件的默认打开方式

D.  文件路径指的是从盘符到该文件所经历的路径中各符号名的集合

❓ C语言中关于文件读写函数说法不正确的是?

A.  fgetc是适用于所有输入流字符输入函数

B.  getchar也是适用于所有流的字符输入函数

C.  fputs是适用于所有输出流的文本行输出函数

D.  fread是适用于文件输入流的二进制输入函数

❓ 下面程序的功能是什么?  

int main()
{ 
  long num=0;
  FILE *fp = NULL;
  if((fp=fopen("fname.dat","r"))==NULL)
  {
    printf("Can’t open the file! ");
    exit(0):
  }
  while(fgetc(fp) != EOF)
  { 
    num++;
  }
  printf("num=%d\n",num);
  fclose(fp);
  return 0;
}

A.  拷贝文件

B.  统计文件的字符数

C.  统计文件的单词数

D.  统计文件的行数

❓ 下面说法不正确的是:

A.  scanf和printf是针对标准输入、输出流的格式化输入、输出语句

B.  fscanf和fprintf是针对所有输入、输出流的格式化输入、输出语句

C.  sscanf是从字符串中读取格式化的数据

D.  sprintf是把格式化的数据写到输出流中

❓ 关于feof函数描述不正确的是:

A.  feof函数是用来判断文件是否读取结束的

B.  feof函数是在文件读取结束的时候,检测是否是因为遇到了文件结束标志EOF,而读取结束

C.  读取文本判断是否结束时,fgetc看返回值是否为EOF, fgets看返回值是否为NULL

D.  二进制文件判断读取结束,看实际读取个数是否小于要求读取个数

二、编程题

1. 文件内容复制

首先在自己编辑器目录下手动创建一个txt文件并命名为 input_1.txt ,文件内容如下:

轻轻的我走了,
正如我轻轻的来;
我轻轻的招手,
作别西天的云彩。
那河畔的金柳,
是夕阳中的新娘;
波光里的艳影,
在我的心头荡漾。

💬 题目要求:通过代码将创建 output_1.txt ,并使用文件操作函数将刚才手动创建的 input_1.txt 文件中的所有内容复制到 output_1.txt 中。

2. 学生成绩分析

首先在自己编辑器目录下手动创建一个txt文件并命名为 input_2.txt ,文件内容如下:

Hellen 90 89.2
Amy 100 52
Jack 22.3 64
Gordon 47.2 100
Brian 56 25.3

💬 题目要求:通过代码将创建 output_2.txt ,并且根据 input_2.txt 中的内容生成下图所示的内容,第一行由学生姓名、平均分、是否合格 构成。算出他们的平均分并且判断是否合格,展现在 output_2.txt 中,要求达到上图所示的效果(缩进随意)。

如果学生的期中期末成绩的平均分高于或等于全班平均分则为 pass,低于全班平均分则为 fail 。

学生的姓名长度限制最多15个字符。

3. 统计文本中所有字母各出现了几次

首先在自己编辑器目录下手动创建一个txt文件并命名为 input_3.txt ,文件内容如下:

Overwatch is a multiplayer team-based first-person shooter developed and published by Blizzard Entertainment.
In a time of global crisis, an international task force of heroes banded together to restore peace to a war-torn world.
This organization, known as Overwatch, ended the crisis and helped maintain peace for a generation, 
inspiring an era of exploration, innovation, and discovery. After many years, Overwatch's influence waned and it was eventually disbanded.
Now in the wake of its dismantling, conflict is rising once again. Overwatch may be gone... but the world still needs heroes.
Choose A Hero: Overwatch features a wide array of unique Heroes, ranging from a time-jumping adventurer, to an armored,
rocket-hammer-wielding warrior, to a transcendent robot monk. Every hero plays differently,
and mastering their Abilities is the key to unlocking their potential.No two heroes are the same.

💬 题目要求:读取 input_3.txt ,统计整个文本中英文字母A~Z分别出现了几次,无视大小写且只统计字母,并打印(格式不要求)。输出结果如下所示:

三、答案与解析

0x00 选择题答案:

❓ C语言以二进制方式打开一个文件的方法是?

A. FILE *f = fwrite( "test.bin", "b" );

B. FILE *f = fopenb( "test.bin", "w" );

C. FILE *f = fopen( "test.bin", "wb" );  ✅

D. FILE *f = fwriteb( "test.bin" );

🔑 解析: 首先要打开文件,所以A的fwrite明显就不对,后面的更离谱。其次B和D是什么勾八玩意 fopenb 又是个what?根本不存在。只有C是对的,首先打开文件,然后以 "wb" 打开一个二进制文件。为了方便加强记忆,附加一张文件使用方式表:

❓ 关于 fopen 函数说法不正确的是?

A.  fopen打开文件的方式是"r",如果文件不存在,则打开文件失败

B.  fopen打开文件的方式是"w",如果文件不存在,则创建该文件,打开成功

C.  fopen函数的返回值无需判断 ✅

D.  fopen打开的文件需要fclose来关闭

🔑 解析:ABD为文件操作的基本概念和原则。C选项中的fopen的返回值可以检验文件是否打开成功,打开方式为 "r" 时尤为重要,所以不能说是无需判断,所以选C。

❓ 下列关于文件名及路径的说法中错误的是?

A.  文件名中有一些禁止使用的字符

B.  文件名中一定包含后缀名

C.  文件的后缀名决定了一个文件的默认打开方式

D.  文件路径指的是从盘符到该文件所经历的路径中各符号名的集合

🔑 解析:A选项,文件名中有禁止中不能包含这些字符:\/:*?"<>|,。C选项,表述了后缀名的作用。D选项,是路径的基本概念。B选项,文件名不一定要包含后缀名,所以选B。

❓ C语言中关于文件读写函数说法不正确的是?

A.  fgetc是适用于所有输入流字符输入函数

B.  getchar也是适用于所有流的字符输入函数

C.  fputs是适用于所有输出流的文本行输出函数

D.  fread是适用于文件输入流的二进制输入函数

🔑 解析:B选项中,getchar只针对标准输入流stdin,即使对stdin重定向,getchar针对的也只是stdin,故选B。f 系列的输入输出函数都是作用于所有流的,所以A和C没有问题。D的表述也没问题,fread 是二进制输入函数,自然就是用来整二进制的活的。

❓ 下面说法不正确的是:

A.  scanf和printf是针对标准输入、输出流的格式化输入、输出语句

B.  fscanf和fprintf是针对所有输入、输出流的格式化输入、输出语句

C.  sscanf是从字符串中读取格式化的数据

D.  sprintf是把格式化的数据写到输出流中 ✅

🔑 解析:D选项中,sprintf是把格式化的数据写到字符串中,与输出流无关。其他三句都准确描述了函数功能。ABC都是正确的,如果不清楚可以看这篇博客:

【C语言】格式化输入输出函数讲解

❓ 关于feof函数描述不正确的是:

A.  feof函数是用来判断文件是否读取结束的 ✅

B.  feof函数是当文件读取结束时,判断是因为读取失败而结束,还是因为遇到文件尾而结束。

C.  读取文本判断是否结束时,fgetc看返回值是否为EOF, fgets看返回值是否为NULL

D.  二进制文件判断读取结束,看实际读取个数是否小于要求读取个数

🔑 解析:说明:feof函数是当文件读取结束时,判断是因为读取失败而结束,还是因为遇到文件尾而结束。并不是判断文件是否读取结束的!

0x01 编程题参考答案(答案仅供参考,答案并不唯一)

1. 文件内容复制【参考答案】

💬 题目要求:通过代码将创建 output_1.txt ,并使用文件操作函数将刚才手动创建的 input_1.txt 文件中的所有内容复制到 output_1.txt 中。

💡 参考答案:

#include <stdio.h>

int main() {
	// 读取刚才创建的文件
	FILE* input_1 = fopen("input_1.txt", "r");
	if (input_1 == NULL) {
		perror("fopen");
		return 1;
	}

	// 创建文件(拷贝目标)
	FILE* output_1 = fopen("output_1.txt", "w");
	if (input_1 == NULL) {
		perror("fopen");
		return 1;
	}

	// 开始操作
	char ch = 0;
	while (1) {
		// 复制
		ch = fgetc(input_1);
		if (ch == EOF) {
			break;
		}
		// 粘贴
		fputc(ch, output_1);
	}

	// 关闭文件
	fclose(input_1);
	fclose(output_1);
	input_1 = NULL;
	output_1 = NULL;

	return 0;
}

🚩 完成结果:

 

2. 学生成绩分析【参考答案】

💬 题目要求:通过代码将创建 output_2.txt ,并且根据 input_2.txt 中的内容生成下图所示的内容,第一行由学生姓名、平均分、是否合格 构成。算出他们的平均分并且判断是否合格,展现在 output_2.txt 中,要求达到上图所示的效果(缩进随意)。

如果学生的期中期末成绩的平均分高于或等于全班平均分则为 pass,低于全班平均分则为 fail 。

学生的姓名长度限制最多15个字符。

💡 参考答案:

#include <stdio.h>

int main(void) {
    char name[15] = { 0 }; // 学生姓名(长度限制15)
    float mid; // 期中考试成绩
    float final; // 期末考试成绩
    float sum = 0.0; // 总合
    float avg = 0.0; // 平均分
    float class_avg = 0.0; // 班级平均分
    int cnt = 0; // 统计
    int res = 0;

    // 读取刚才创建的文件
    FILE* input_2 = fopen("input_2.txt", "r");
    if (input_2 == NULL) {
        perror("fopen");
        return 1;
    }

    // 创建文件(目标)
    FILE* output_2 = fopen("output_2.txt", "w");
    if (output_2 == NULL) {
        perror("fopen");
        return 1;
    }

    // 读取学生姓名、期中成绩和期末成绩
    while (1) {
        res = fscanf(input_2, "%s%f%f", name, &mid, &final);
        if (res == EOF) {
            break;
        }
        sum += mid + final;
        cnt += 2;
    }

    // 关闭文件
    fclose(input_2);

    // 再次打开
    input_2 = fopen("input_2.txt", "r");
    if (input_2 == NULL) {
        perror("fopen");
        return 1;
    }

    // 计算班级平均分
    class_avg = sum / cnt;
    // 写入第一行标题
    fprintf(output_2, "strudent        average grade\n");
    // 写入数据
    while (1) {
        res = fscanf(input_2, "%s%f%f", name, &mid, &final);
        if (res == EOF) {
            break;
        }
        // 计算个人平均分
        avg = (mid + final) / 2;
        // 判断是否合格 pass or fail
        if (avg >= class_avg) {
            fprintf(output_2, "%-10s      %.2f   pass\n", name, avg);
        } else {
            fprintf(output_2, "%-10s      %.2f   fail\n", name, avg);
        }
    }
    fprintf(output_2, "Class average:  %.2f", class_avg);


    // 关闭文件
    fclose(input_2);
    fclose(output_2);
    input_2 = NULL;
    output_2 = NULL;

    return 0;
}

🚩 完成结果:

3. 统计文本中所有字母各出现了几次【参考答案】

💬 题目要求:读取 input_3.txt ,统计整个文本中英文字母A~Z分别出现了几次,无视大小写且只统计字母,并打印(格式不要求)。输出结果如下所示:

💡 参考答案:

① 直接用库函数进行大小写转换:

#include <stdio.h>
#include <ctype.h>

int main(void) {
    int alp[26] = { 0 }; // 字母表
    
    // 读取刚才创建的文件
    FILE* input_3 = fopen("input_3.txt", "r");
    if (input_3 == NULL) {
        perror("fopen");
        return 1;
    }
 
    int ch = 0;
    while (ch = fgetc(input_3), ch != EOF) {
        // 大小写转换(题目要求无视大小写)
        if (isupper(ch)) {
            ch = tolower(ch);
        }
        if (islower(ch)) {
            alp[ch - 'a'] += 1;
        }
    }

    //打印结果
    int i = 0;
    for (i = 0; i < 26; i++) {
        printf("[%c]:%d\t", 'A' + i, alp[i]);
    }

    // 关闭文件
    fclose(input_3);
    input_3 = NULL;

    return 0;
}

② 用ASCII码的特性进行大小写转换:

#include <stdio.h>

int main(void) {
    int alp[26] = { 0 }; // 字母表
    
    // 读取刚才创建的文件
    FILE* input_3 = fopen("input_3.txt", "r");
    if (input_3 == NULL) {
        perror("fopen");
        return 1;
    }
 
    int ch = 0;
    while (ch = fgetc(input_3), ch != EOF) {
        // 大小写转换(题目要求无视大小写)
        if ('A' <= ch && ch <= 'Z') {
            ch -= 'A' - 'a';
        }
        if ('a' <= ch && ch <= 'z') {
            alp[ch - 'a'] += 1;
        }
    }

    //打印结果
    int i = 0;
    for (i = 0; i < 26; i++) {
        printf("[%c]:%d\t", 'A' + i, alp[i]);
    }

    // 关闭文件
    fclose(input_3);
    input_3 = NULL;

    return 0;
}


参考资料:

📌 作者:王亦优

📃 更新: 2021.10.14

❌ 勘误: 无

📜 声明: 由于作者水平有限,本文有错误和不准确之处在所难免,本人也很想知道这些错误,恳望读者批评指正!

本篇完。

本文标签: 选择题语言操作文件章节