实验七

---恢复内容开始---

Part1: 验证性实验 

验证性实验1:已知文件file1.txt已经存在,将file1.txt中小写字母转换成大写后,另存为file2.txt

// 将file1.txt中小写字母转换成大写后,另存为file2.txt 
#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *fin, *fout; // 定义文件类型指针
    int ch;
    
    fin = fopen("file1.txt", "r"); // 以只读文本方式打开文件file1.txt
    if (fin == NULL) {
        printf("fail to open file1.txt\n");
        exit(0);    
    } 
    
    fout = fopen("d:\\file3.txt", "w"); // 以写文本方式打开文件file2.txt, 如果文件不存在,就创建一个
    if (fout == NULL) {
        printf("fail to open or create file2.txt\n");
        exit(0);
    } 
    
    while( !feof(fin) ) {
        ch = fgetc(fin);  // 从fin指向的文件file1.txt中读取单个字符,暂存在字符变量ch中 
        
        if(ch >= 'a' && ch <= 'z')  // 如果是小写字母,则转换成大写 
            ch -= 32;
        
        fputc(ch, fout); // 将字符变量ch中的字符写入fout指向的文件file2.txt中 
    }
    
    fclose(fin);    
    fclose(fout);
    
    return 0;
}

1、调用方式通常为:

FILE *fp;
fp=fopen(文件名, 打开方式);
 
2.参数
"r"(只读) 为输入打开一个文本文件
  "w"(只写) 为输出打开一个文本文件
  "a"(追加) 向文件文件尾添加数据
  "rb"(只读) 为输入打开一个二进制文件
  "wb"(只写) 为输出打开一个二进制文件
  "r+"(读写) 为读写打开一个文本文件
  "w+"(读写) 为读写建立一个新的文本文件
  "a+"(读写) 为读写打开一个文本文件
  "rb+"(读写) 为读写打开一个二进制文件
  "wb+"(读写) 为读写建立一个新的二进制文件
  "ab+"(读写) 为读写打开一个二进制文件
3、注意:
  (1)用"r"方式打开的文件,不能向其输入数据,并且该文件已存在,否则出错;
  (2)用"w"方式打开的文件,只能向该文件输入数据,如果所打开的文件不存在,则在打开时新建一个以指定的名字命名的文件;如果指定文件存在,则在打开时将该文件删去,然后新建一个新的文件;
  (3)如果函数fopen打开文件出错,则fopen返回一个空指针值NULL;
**********************************************************************************************************************************************************************

尝试对line15做如下修改,在文件名前加上绝对路径:
观察此时当前路径下是否有file3.txt。观察电脑的d盘下是否有文件file3.txt,如果有,打开观察其内容。

A:若无,建立file.3,若有,原文件被覆盖。

 

验证性实验2:

从文件file1.dat中读入数据,找出最高分和最低分学生信息,并输出在屏幕上。

改动line29行:

// 从文本文件file1.dat中读取数据,找出最高分和最低分学生信息,并输出在屏幕上
#include <stdio.h> 
#include <stdlib.h>

#define N 

// 定义一个结构体类型STU 
typedef struct student {
    int num;
    char name[20];
    int score;
}STU;

int main() {
    STU st, stmax, stmin;
    int i;
    FILE *fp;
    
    // 以只读文本方式打开文件file1.dat 
    fp = fopen("file1.dat", "r");
    if( !fp ) {  // 如果打开失败,则输出错误提示信息,然后退出程序 
        printf("fail to open file1.dat\n");
        exit(0);
    }
    
    stmax.score = 0;    // 先假定最高分是0,后面如发现比当前最高分还高的分数,就更新最高分 
    stmin.score = 100;    // 先假定最低分是100分,后面如发现比当前最低分更低的分数,就更新最低分 
    
    while(!feof(fp)) {
        fscanf(fp, "%d %s %d", &st.num, st.name, &st.score);  // 从fp指定的文件中格式化读取一个学生信息
        
        if(st.score > stmax.score)
            stmax = st;
        else if(st.score < stmin.score)
            stmin = st; 
    } 
    
    fclose(fp);
    
    printf("最高分学生信息: %5d%15s%5d\n", stmax.num, stmax.name, stmax.score);
    printf("最低分学生信息: %5d%15s%5d\n", stmin.num, stmin.name, stmin.score);

    return 0;
}

 

 

在未知人数的情况下,改后可以运行,feof()就是站在光标所在位置,向后看看还有没有字符。如果有,返回0;如果没有,返回非0。它并不会读取相关信息,只是查看光标后是否还有内容。返回0后光标向后移动,直至后面面没有字符结束返回非0.

 

验证性实验3:

      

 验证性实验4:

 从文件file1.dat中读入数据,按成绩从高到低排序,将排序结果输出到屏幕上,同时也以二进制方式存入文件 file4.dat中。

 

文本文件和二进制文件区别:

二进制文件就是把内存中的数据按其在内存中存储的形式原样输出到磁盘中存放,即存放的是数据的原形式。

文本文件是把数据的终端形式的二进制数据输出到磁盘上存放,即存放的是数据的终端形式。

 

Part2: 编程练习

改写「实验6」中的「编程练习2」,使得成绩信息从文本文件examinee.txt读入,计算后的结果不仅在屏幕上 显示,也写入文本文件result.txt中。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const int N = 10;

// 定义结构体类型struct student,并定义其别名为STU 
typedef struct student {
    long int id;
    char name[20];
    float objective;    /*客观题得分*/
    float subjective;    /*操作题得分*/
    float sum;
    char level[10];    
}STU; 

// 函数声明
void input(STU s[], int n);
void output(STU s[], int n);
void process(STU s[], int n);

int main() {
    STU stu[N];
    
    printf("录入%d个考生信息: 准考证号,姓名,客观题得分(<=40),操作题得分(<=60)\n", N); 
    input(stu, N);
    
    printf("\n对考生信息进行处理: 计算总分,确定等级\n");
    process(stu, N);
    
    printf("\n打印考生完整信息: 准考证号,姓名,客观题得分,操作题得分,总分,等级\n");
    output(stu, N); 
    
    return 0;
} 

// 从文本文件examinee.txt读入考生信息:准考证号,姓名,客观题得分,操作题得分
void input(STU s[], int n) {
    FILE *fin;
    int i;
    if((fin=fopen("examinee.txt","r"))==NULL)
    {printf("cannot open file");
    exit(0);
    }
    for(i=0;i<n;i++)
    fscanf(fin,"%d %s %f %f",&s[i].id,s[i].name,&s[i].objective,&s[i].subjective);
    
     fclose(fin);
}

// 输出考生完整信息: 准考证号,姓名,客观题得分,操作题得分,总分,等级
// 不仅输出到屏幕上,还写到文本文件result.txt中 
void output(STU s[], int n) {
    FILE *fout;
    int i;
    if((fout=fopen("result.txt","w"))==NULL)
    {printf("cannot open file");
    exit(0);
    }
     for(i=0;i<n;i++){
         printf("%5d %10s   %5.1f %5.1f %5.1f %5s\n",s[i].id,s[i].name,s[i].objective,s[i].subjective,s[i].sum,s[i].level);
     fprintf(fout,"%5d %10s   %5.1f %5.1f %5.1f %5s\n",s[i].id,s[i].name,s[i].objective,s[i].subjective,s[i].sum,s[i].level);

}
   fclose(fout);
}
// 对考生信息进行处理:计算总分,排序,确定等级
void process(STU s[], int n) {
    int i,j;
    STU temp;
    for(i=0;i<n;i++){
        s[i].sum=0.4*s[i].objective+0.6*s[i].subjective;
    }
    for(i=0;i<n-1;i++){
        for(j=0;j<n-i-1;j++){
            if(s[j].sum<s[j+1].sum){
                temp=s[j];
                s[j]=s[j+1];
                s[j+1]=temp;
            }
        }
    }
    for(i=0;i<n;i++){
        if(i<0.1*n)
           strcpy(s[i].level,"");
        else if(i<0.5*n&&i>=0.1*n)
           strcpy(s[i].level,"");
        else if(i>=0.5*n)
          strcpy(s[i].level,"不合格"); 
    }
}

在用于输出时:
float类型可以使用%lf格式,但不会有任何好处。
double类型如果使用了%f格式可能会导致输出错误。

在用于输入时:
double 类型使用了%f格式,会导致输入值错误。
float类型使用double类型不仅会导致输入错误,还可能引起程序崩溃。

fscanf里一开始用的lf,输出都是零分,检查了很久发现数据类型错了。。

实验总结

文件这块因为是建立在函数基础上新的内容,写的时候比较小心注意格式反而没犯什么错,依然在中英文切换输入字符上一不留神就错了,或是手滑就打错了符号,自己也检查不出来,还是要在写的时候就注意。

 

posted @ 2019-06-19 11:12  奥利奥利奥qxy  阅读(203)  评论(2编辑  收藏  举报