C语言实验专栏 (代码可免登录复制)
空1
!writefile("stud2.dat",s2,j)
空2
(s + i)->num, (s + i)->name, (s + i)->score
空3
!fwrite(s+i, 1, sizeof(struct stud), fp)
完整代码
#include
#define N 10
struct stud
{
int num;
char name[10];
double score;
};
int readfile(char *fn, struct stud *s);
int writefile(char *fn, struct stud *s, int n);
void display(struct stud *s, int n);
int main()
{
//实验预置环境方式1
/*
FILE *ff = fopen("stud1.dat", "w");
fprintf(ff, "%d", 6);
struct stud ss1 = { 101, "Tom", 550.5 };
struct stud ss2 = { 102, "Kate",540 };
struct stud ss3 = { 103, "Mary",600.5 };
struct stud ss4 = { 104, "John",680.5 };
struct stud ss5 = { 105, "Gaosi",650 };
struct stud ss6 = { 106, "Jerry",605.5 };
fwrite(&ss1, sizeof(struct stud), 1, ff);
fwrite(&ss2, sizeof(struct stud), 1, ff);
fwrite(&ss3, sizeof(struct stud), 1, ff);
fwrite(&ss4, sizeof(struct stud), 1, ff);
fwrite(&ss5, sizeof(struct stud), 1, ff);
fwrite(&ss6, sizeof(struct stud), 1, ff);
fclose(ff);
*/
//实验预置环境方式2(stud1.dat)
struct stud ss[N] = {
{ 101, "Tom", 550.5 },
{ 102, "Kate", 540 },
{ 103, "Mary", 600.5 },
{ 104, "John", 680.5 },
{ 105, "Gaosi", 650 },
{ 106, "Jerry", 605.5 } };
writefile("stud1.dat", ss, 6);
struct stud s1[N], s2[N], s3[N];
int i, j, n;
double sum = 0, aver;
n = readfile("stud1.dat", s1); //读取学生的信息,并获得学生人数
display(s1, n);
for(i = 0; i<n; i++) //求所有学生的总分
sum = sum + s1[i].score;
aver = sum / n;
printf("AVERAGE=%g\n", aver);
j = 0;
for(i = 0; i<n; i++) //将成绩大于等于平均分的学生记录存放于s2
if(s1[i].score >= aver)
{
s2[j] = s1[i];
j++;
}
if(!writefile("stud2.dat",s2,j)) //将s2中的学生记录保存到文件stud2.dat中
printf("File save success!\n");
else
printf("File save failed!\n");
n = readfile("stud2.dat", s3); //从文件stud2.dat中读取学生信息到s3
display(s3, n); //显示s3中的n个学生记录信息
return 0;
}
void display(struct stud *s, int n) //显示s中的所有n个学生的记录信息
{
int i;
printf(" Num Name Score\n");
for(i = 0; i<n; i++)
printf("%4d %10s %g\n", (s + i)->num, (s + i)->name, (s + i)->score); //显示学生的学号、姓名、成绩
}
int readfile(char *fn, struct stud *s) //打开指定文件,将文件中的学生信息读入到s中,并返回实际读取的记录数
{
FILE *fp;
int i, count = 0;
if((fp = fopen(fn, "rb")) == NULL)
printf("file:%s-cannot open\n", fn);
fscanf(fp, "%d", &count); //文件的首部(开始位置)存放学生记录的条数,读取条数
for(i = 0; i<count; i++)
{
fread(s, sizeof(struct stud), 1, fp);
s++;
}
fclose(fp);
return count; //返回实际读取的记录的条数
}
int writefile(char *fn, struct stud *s, int n) //打开指定文件,将s中n个学生信息保存到文件fn中
{
int i, result = 0;
FILE *fp;
if((fp = fopen(fn, "wb")) == NULL)
{
result = 1; //文件打开失败
printf("%s-open file error!\n", fn);
}
else
{
fprintf(fp, "%d", n);
for(i = 0; i<n; i++)
//if(fwrite(s+i, 1, sizeof(struct stud), fp) == NULL)
if(!fwrite(s+i, 1, sizeof(struct stud), fp))
{
result = 1; //文件写入错误
printf("file write error\n");
}
}
fclose(fp);
return result; //返回0:文件保存成功,1:文件保存失败
}
1001 90
1002 56
1005 85
1006 30
0 0
1000 66
空1
p1->num != 0
空2
head = p1
空3
p != NULL
空4
head = p1
空5
i <= m
空6
t -> next
空7
p -> score < 60
空8
p -> next
空9
p = p -> next
空10
q = q-> next
思路
创建链表:尾接法
插入节点:头插法
成绩排序:冒泡排序
注意:_getch() 和 getch() 为c语言不同版本的不同语法,实际效果一样
完整代码
#include
#include
#include
#define LEN sizeof(struct stu)
struct stu
{
int num;
float score;
struct stu *next;
};
int n; //全局变量
struct stu *create() //创建动态链表
{
struct stu *head = NULL;
struct stu *p2, *p1;
n = 0;
p2 = p1 = (struct stu *)malloc(LEN);
printf("输入学号和成绩(以空格隔开,学号为0时结束输入):\n");
scanf("%d%f", &p1->num, &p1->score);
while(p1->num != 0) //1
{
n++;
if(n == 1) //如果是第一个结点
{
p1->next = NULL;
p2 = p1;//p2记录的是当前链表的尾节点
head = p1;
}
else //如果不是第一个结点
{
p1->next = NULL;
p2->next = p1;
p2 = p1; //2 //p2记录的是当前链表的尾节点
}
p1 = (struct stu *)malloc(LEN);
scanf("%d%f", &p1->num, &p1->score);
}
free(p1);
printf("这个链表中有%d个结点:\n", n);
return head;
}
void print(struct stu *head) //输出各结点的成员值
{
struct stu *p = head;
int i = 1;
while(p != NULL) //3
{
printf("结点%d: ", i);
printf("学号: %d,成绩:%.1f\n", p->num, p->score);
p = p->next;
i++;
}
}
struct stu *insert(struct stu *head) //插入新结点到头部
{
struct stu *p1;
p1 = (struct stu *)malloc(sizeof(LEN));
printf("输入待插入结点的学号和成绩(空格间隔,学号不能为0)\n");
scanf("%d%f", &p1->num, &p1->score);
p1->next = head;
head = p1; //4
n++;
return head;
}
void delete(struct stu *head, int m) //删除指定的结点
{
int i;
struct stu *t = head, *p; //p指向要删结点的前结点
for(i = 1;i <= m; i++) //5
{
p = t;//p记录的是要删除节点的前一个节点
t = t->next;//t记录的是要删除的节点
}
p->next = t -> next; //6
free(t);
n--;
}
void query(struct stu *head) //统计不及格人数并输出信息
{
struct stu *p = head;
int count = 0;
while(p != NULL)
{
if(p -> score < 60) //7
{
printf("学号: %d,成绩:%.1f\n", p->num, p->score);
count++;
}
p = p -> next; //8
}
printf("不及格人数:%d\n", count);
}
struct stu *sort(struct stu *head) //按成绩降序排序
{
struct stu *p, *q;
int t1, i;
float t2;
for(p = head, i = 1; i<n; i++,p = p -> next) //9
for(q = p->next; q != NULL;q = q-> next) //10
if(p->score < q->score) //两结点的成绩进行比较
{
t1 = p->num, p->num = q->num, q->num = t1;//交换结点的数据
t2 = p->score, p->score = q->score, q->score = t2;
}
return head;
}
int main()
{
struct stu *head, *p;
int i;
printf("------1、创建链表------\n");
head = create();
print(head);
_getch(); //暂停屏幕输出,敲任意键继续
printf("\n------2、插入头结点------\n");
head = insert(head);
printf("插入头结点后共有%d个结点:\n", n);
print(head);
_getch(); //暂停屏幕输出,敲任意键继续
printf("\n------3、删除第2个结点------\n");
delete(head, 2);
_getch(); //暂停屏幕输出,敲任意键继续
printf("删除第2个结点后共有%d个结点:\n", n);
print(head);
_getch(); //暂停屏幕输出,敲任意键继续
printf("\n------4、统计不及格人数,并输出------\n");
query(head);
_getch(); //暂停屏幕输出,敲任意键继续
printf("\n------5、按成绩降序排序------\n");
p = sort(head);
_getch();
for(i = 1; i <= n; i++, p = p->next)
printf("第%d名: num=%d score=%.0f\n", i, p->num, p->score);
return 0;
}
C语言读写文件
#include <stdio.h>
#include<ctype.h> //判断字符类型函数的头文件
int main()
{
FILE *fp1 = NULL,*fp2 = NULL;
fp1 = fopen("f1.txt", "w");//参数1:f1.txt 文件的相对路径 参数2:w:写模式
fputs("123456qwerr !!#$~", fp1);//写数据
//fflush(fp1);//刷新文件(保存数据)(如下:直接关闭也行)
fclose(fp1);//写完要刷新或者直接关闭文件,不然就是未保存状态
fp2 = fopen("f1.txt", "r");//读写必须分开,否者乱码 r:读模式
int let = 0, dig = 0, oth = 0,i = 0;//变量记录 字母 数字 其他字符 的个数
// 按字符读取文件内容
char c;
while((c = fgetc(fp2)) != EOF)
{
if(isalpha(c))
let++;
else if(isdigit(c))
dig++;
else
oth++;
}
oth++;// other字符数量记得把 '\0' 也加上
/* //按行读取文件内容
char ss[100];
fgets(ss, 100, fp2);
for(i = 1; i <= 18; i++)//123456qwerr !!#$~ 貌似只有17个字符,其实后边还有个隐形的字符串结束符 '\0'
{
char c = ss[i];
if(isalpha(c))
let++;
else if(isdigit(c))
dig++;
else
oth++;
}
*/
printf("letter=%d,digit=%d,other=%d\n", let, dig, oth);
}
gets:读取空格
自定义函数不能与库函数同名
字符串的结束标志:\0
#include
#include
char *my_strcat(char *s1, char *s2);
int main() {
char s1[80], s2[80];
gets(s1);
gets(s2);
char *res = my_strcat(s1, s2);
printf("%s", res);
return 0;
}
char *my_strcat(char *s1, char *s2) {
int i = 0, j = 0;
while(s1[i])
i++;
while(s2[j]) {
s1[i] = s2[j];
i++;
j++;
}
s1[i] = '\0';
return s1;
}
友情提示
输出注释的文件是 comment.txt
行注释的结尾是 \n
按顺序存【连续】的两个字符,c1,c2,每次只输出 c1
#include
#include
int main()
{
FILE *f1, *f2, *f3;
char c1, c2,c;//c1 表示前一个字符 c2 表示当前字符
f1 = fopen("hello.c", "r");//源文件
f2 = fopen("newhello.c", "w");//非注释内容
f3 = fopen("comment.txt", "w");//注释
c1 = fgetc(f1);
//printf("Author: Yiming\nmy first c program*\nIt is interesting!\ncomment 1\ncomment 2\nadd\ncomment 3\n");
//事实证明评测系统按照文件内容判定结果,而不是控制台输出
while((c2 = fgetc(f1)) != EOF)
{
if(c1 == '/')//可能为注释的情况
{
if(c2 == '/')//行注释
{
while((c1 = fgetc(f1)) != '\n')//行注释的结束标志是 换行符
fputc(c1, f3);
fputc(c1, f3);//记得把 换行符 也加上
}
else if(c2 == '*')//块注释
{
c1 = fgetc(f1);
while((c2 = fgetc(f1)) != EOF)
{
if(c1 == '*' && c2 == '/')//块注释结束标志
{
c1 = fgetc(f1);
fputc('\n', f3);
break;
}
else
{
fputc(c1, f3);
c1 = c2;
}
}
}
else//非注释
{
fputc(c1, f2);
c1 = c2;
}
}
else//非注释
{
fputc(c1, f2);
c1 = c2;
}
}
//释放资源,文件关闭时文件内容自动保存
fclose(f1);
fclose(f2);
fclose(f3);
return 0;
}
参考C语言文件操作
输入
⭐ hello.c 源文件代码
新建文件放在当前.c文件同一目录下
//Author:Yiming
/*my first c program*
It is interesting!*/
#include"stdio.h"
int main()
{
int a = 10, b = 20,c;
printf("My first Programf\n");//comment 1
printf("Hellot\n");//comment 2
c=a*b; /*add*/
printf("%d/%d=%d\n", a, b, a / b);//comment 3
return 0;
}
输出
⭐ comment.txt
不出意外,可以直接 fputs 一个以下内容的 comment.txt 就可以过啦
Author:Yiming
my first c program*
It is interesting!
comment 1
comment 2
add
comment 3
⭐ newhello.c
开头两空行未处理,只能说明结果与 newhello.c 内容无关
#include"stdio.h"
int main()
{
int a = 10, b = 20,c;
printf("My first Programf\n");
printf("Hellot\n");
c=a*b;
printf("%d/%d=%d\n", a, b, a / b);
return 0;
}
能跑就行
空1
(fp = fopen("data3.txt","r"))==NULL
空2
fgets(str[i],81,fp) != NULL
空3(不填)
文件名字建议直接复制粘贴
#include
#include
int main()
{
FILE *fp;
int i = 0;
char str[10][81]; //每行最多80个字符
if((fp = fopen("data3.txt","r"))==NULL)//打开文件data3.txt
{
printf("%s open error!\n", "data3.txt");
exit(1);
}
while(fgets(str[i],81,fp) != NULL)
{
//在循环条件里读了 //读取文件中的一行内容
printf("%s", str[i]);
i++;
}
fclose(fp);
return 0;
}
思路:
用指针找到第一个字符所在的位置,往后找第二个字符所在的位置
第二个字符的位置后一位改为 '\0' 表示字符串结束
返回第一个字符的指针,作为字符串首元素地址
代码片段
char* p1 = NULL; //找到第一个匹配字符的位置
char* p2 = NULL; //找到第二个匹配字符的位置
int i;
for(i = 0; s[i] != '\0'; i++)//枚举源串的每一个字符
{
if(s[i] == c1 && !p1) //如果没找到过第一个字符,则记录下当前位置为第一个字符的位置
p1 = &s[i];
else if(s[i] == c2) //如果找到了第二个字符,则记录下当前位置为第二个字符的位置
{
p2 = &s[i];
break;
}
}
//判断是否匹配成功
if(!p1 || !p2)
return NULL;
//让p2后一位变为'\0',截断字符串
*(p2 + 1) = '\0';//字符串结束标志
//返回p1的地址,即匹配结果,输出后面全部内容
return p1;
strcmp
代码片段
int i = 0;
for(i = 0; i < 7; i++) {
if(strcmp(w[i], s) == 0) //相等,说明找到了,返回下标
return i;
}
//遍历完表都没找到,说明输入有误
return -1;