结构体嵌套练习

在这里我们创建一个结构体数组,该数组有三名老师,每名老师又带有三名同学,我们分别给他们赋值,最后根据老师的名字进行降序排列。

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> //结构体类型,每个导师有3个学生 typedef struct Teacher { char* tName;//导师 char** stu;// int age; }Teacher; //在createTeacher中分配空间 int createTeacher(Teacher** p, int n1, int n2) { if (p==NULL) { return -1; } Teacher* temp = NULL;//Teacher temp[3] temp = (Teacher*)malloc(n1 * sizeof(Teacher)); if (temp==NULL) { return -2; } for (int i = 0; i < n1; i ) { //导师 temp[i].tName = (char*)malloc(30);//3个老师 //学生 char** s = (char**)malloc(n2 * sizeof(char*));//3个学生的指针变量 for (int j = 0; j < n2; j )//给3个学生分配堆空间 { s[j] = (char*)malloc(30); } //直接赋值 temp[i].stu = s; } //间接赋值 *p = temp; return 0; } //给成员赋值 void initTeacher(Teacher* p, int n1, int n2) { if (p==NULL) { return; } char buf[30]; for (int i = 0; i < n1; i ) { //导师名字 sprintf(buf, "teacher%d%d%d", i, i, i); strcpy(p[i].tName, buf); //年龄 p[i].age = 30 2 * i; //学生 for (int j = 0; j < n2; j ) { sprintf(buf,"stu%d%d%d%d", i, i, j, j); strcpy(p[i].stu[j], buf); } } } //打印结构体成员信息 void printTeacher(Teacher* p, int n1, int n2) { if (p==NULL) { return; } for (int i = 0; i < n1; i ) { //年龄 printf("%s[%d]\n", p[i].tName, p[i].age); //学生 for (int j = 0; j < n2; j ) { printf("\t%s", p[i].stu[j]); } printf("\n"); } } //根据导师名字排序,降序 void sortTeacher(Teacher* p, int n) { if (p==NULL) { return; } Teacher temp; for (int i = 0; i < n-1; i ) { for (int j = i 1; j < n; j ) { if (strcmp(p[i].tName,p[j].tName)<0) { temp = p[i]; p[i] = p[j]; p[j] = temp; } } } } //释放空间,在函数内部把p赋值为NULL void freeTeacher(Teacher** p, int n1, int n2) { if (p==NULL) { return; } Teacher* temp = *p; for (int i = 0; i < n1; i ) { //释放导师 if (temp[i].tName!=NULL) { free(temp[i].tName); temp[i].tName = NULL; } //释放学生 for (int j = 0; j < n2; j ) { if (temp[i].stu[j]!=NULL) { free(temp[i].stu[j]); temp[i].stu[j] = NULL; } } if (temp[i].stu != NULL) { free(temp[i].stu); temp[i].stu = NULL; } } if (temp!=NULL) { free(temp); *p = NULL; } } int main() { int ret = 0; int n1 = 3;//导师个数 int n2 = 3;//学生 Teacher* p = NULL; ret = createTeacher(&p, n1, n2); if (ret!=0) { printf("createTeacher err:%d\n", ret); return ret; } initTeacher(p, n1, n2);//给成员赋值 //打印成员,排序前 printf("排序前:\n"); printTeacher(p, n1, n2); //根据导师姓名排序,降序 sortTeacher(p, n1); //打印成员,排序后 printf("排序后\n"); printTeacher(p, n1, n2); //释放空间,在函数内部把p赋值为null freeTeacher(&p, n1, n2); printf("\n"); return 0; }

c语言读取文件字符的行数(C语言文件的随机读写)(1)

打印结果

按照字符读写文件fgetc、fputc的使用

fgetc():

int fgetc(FILE *stream)

参数:

返回值

该函数以无符号 char 强制转换为 int 的形式返回读取的字符,如果到达文件末尾或发生读错误,则返回 EOF。

fputc():

int fputc(int char, FILE *stream)

参数:

返回值:

如果没有发生错误,则返回被写入的字符。如果发生错误,则返回 EOF,并设置错误标识符。

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> int main0301() { fputc('a', stdout);//将字符a输出到屏幕,打印普通信息 char ch; ch = fgetc(stdin);//从键盘输入字符放到ch中 printf("ch=%c", ch); fprintf(stderr, "%c", ch);//stderr指向屏幕,打印错误信息 fputc(ch, stderr); return 0; } int main0302() { FILE* fp = NULL; //相对路径, / , ./ , ../ linux与windows均可 //vs:编译代码时,相对于项目工程 //直接运行可执行程序,相对于程序 char* p = "aaaaaaaaaa" "bbbbbbbbbbbb"; //字符串换行 printf("%s\n", p); fp = fopen("./a.txt", "w "); if (fp!=NULL) { fclose(fp); fp == NULL; } return 0; } void my_fputc(char* path) { FILE* fp = NULL; // w 表示可写可读方式打开 若文件不存在,则创建文件 // 若文件存在 则清空文件内容再写 fp = fopen(path, "w "); if (fp==NULL) { perror("fopen"); return; } //写文件 char buf[] = "Today is saturday"; for (int i = 0; i < strlen(buf); i ) { //返回值是成功写入文件的字符 int ch = fputc(buf[i], fp); printf("ch=%c\n", ch); } if (fp!=NULL) { fclose(fp); fp = NULL; } } void my_fgetc(char*path) { //以文件读写方式打开,如果文件不存在 打开失败 FILE* fp = fopen(path, "r "); if (fp==NULL) { perror("my_fgetc fopen"); return; } char ch; while (ch=fgetc(fp)!=EOF) { printf("%c ", ch); } printf("\n"); while (!feof(fp))//文件没有结束执行循环 { ch = fgetc(fp); printf("%c ", ch); } printf("\n"); if (fp!=NULL) { fclose(fp); fp = NULL; } } int main() { // my_fputc("../a.txt"); my_fgetc("../a.txt"); return 0; }

按照行读写文件fputs、fgets

fgets():

char *fgets(char *str, int n, FILE *stream)

fputs():

int fputs(const char *str, FILE *stream)

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> void my_fputs(char* path) { FILE* fp = NULL; // w 表示可写可读方式打开 若文件不存在,则创建文件 // 若文件存在 则清空文件内容再写 fp = fopen(path, "w "); if (fp == NULL) { perror("fopen"); return; } char* buf[] = { "aaa\n","bbb\n","ccc\n" }; for (int i = 0; i < strlen(buf); i ) { //返回值是成功写入文件个数,成功返回0,失败非0 int len = fputs(buf[i], fp); printf("len=%d\n", len); } if (fp != NULL) { fclose(fp); fp = NULL; } } void my_fgets(char* path) { //以文件读写方式打开,如果文件不存在 打开失败 FILE* fp = fopen(path, "r "); if (fp == NULL) { perror("my_fgets fopen"); return; } char buf[100] = { 0 }; while (!feof(fp)) { //fgets 的返回值,成功返回读取文件内容 //fgets读取完毕后,字符串末尾自动加0 //会将\n读取,并且以\n作为换行标志 char* p = fgets(buf, sizeof(buf), fp); printf("buf=%s\n", buf); printf("%s ",p); } printf("\n"); if (fp != NULL) { fclose(fp); fp = NULL; } } int main() { my_fputs("../04.txt"); my_fgets("../04.txt"); return 0; }

c语言读取文件字符的行数(C语言文件的随机读写)(2)

打印结果

按照块读写文件fread、fwrite

fread():

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)

成功读取的元素总数会以 size_t 对象返回,size_t 对象是一个整型数据类型。如果总数与 nmemb 参数不同,则可能发生了一个错误或者到达了文件末尾

fwrite():

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)

如果成功,该函数返回一个 size_t 对象,表示元素的总数,该对象是一个整型数据类型。如果该数字与 nmemb 参数不同,则会显示一个错误。

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> typedef struct Stu { char name[50]; int id; }Stu; void my_fwrite(char*path) { FILE* fp = fopen(path, "w "); if (fp == NULL) { perror("my_write fopen"); return; } Stu s[3]; char buf[50]; for (int i = 0; i < 3; i ) { sprintf(buf, "stu%d%d%d", i, i, i); strcpy(s[i].name, buf); s[i].id = i 1; } //按块写文件 //s 写入文件内容的首地址 //sizeof(Stu) 块数据的大小 //3 块数 写文件的数据大小 sizeof(Stu)*3 //fp 文件指针 //返回值 成功写入文件的块数 int ret = fwrite(s, sizeof(Stu), 3, fp); printf("ret=%d\n", ret);//3 if (fp != NULL) { fclose(fp); fp = NULL; } } void my_fread(char** path) { FILE* fp = fopen(path, "r "); if (fp == NULL) { perror("my_fread fopen"); return; } Stu s[3]; char buf[50]; for (int i = 0; i < 3; i ) { sprintf(buf, "stu%d%d%d", i, i, i); strcpy(s[i].name, buf); s[i].id = i 1; } //按块读文件 //s 放文件内容首地址 //sizeof(Stu) 块数据的大小 //3 块数 读文件的数据大小 sizeof(Stu)*3 //fp 文件指针 //返回值 成功读出文件的块数 int ret = fread(s, sizeof(Stu), 3, fp); printf("ret=%d\n", ret);//3 for (int i = 0; i < 3; i ) { printf("%s,%d\n", s[i].name, s[i].id); } if (fp != NULL) { fclose(fp); fp = NULL; } } int main() { my_fwrite("../05.txt"); my_fread("../05.txt"); return 0; }

c语言读取文件字符的行数(C语言文件的随机读写)(3)

打印结果

按照格式化读写文件fprintf、fscanf

fprintf():

int fprintf(FILE *stream, const char *format, ...)

fscanf():

int fscanf(FILE *stream, const char *format, ...)

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> void my_fprintf(char**path) { FILE* fp = fopen(path, "w "); if (fp == NULL) { perror("my_fprintf fopen"); return; } //printf("hello world%d\n", 001); //fprintf(stdout, "hello world%d\n", 001);//实际结果与上相同 fprintf(fp, "%d %d %d\n", 001,2,3); if (fp != NULL) { fclose(fp); fp = NULL; } } void my_fscanf(char** path) { FILE* fp = fopen(path, "r "); if (fp == NULL) { perror("my_fscanf fopen"); return; } //printf("hello world%d\n", 001); //fprintf(stdout, "hello world%d\n", 001);//实际结果与上相同 int a = 0; int b = 0; int c = 0; fscanf(fp, "%d %d %d\n", &a,&b,&c); printf("a=%d,b=%d,c=%d\n", a,b,c); if (fp != NULL) { fclose(fp); fp = NULL; } } int main() { my_fprintf("../06.txt"); my_fscanf("../06.txt"); return 0; }

文件的随机读写fseek函数的使用

fseek():

int fseek(FILE *stream, long int offset, int whence)

SEEK_SET

文件的开头

SEEK_CUR

文件指针的当前位置

SEEK_END

文件的末尾

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> typedef struct Stu { char name[50]; int id; }Stu; void my_fwrite(char* path) { FILE* fp = fopen(path, "w "); if (fp == NULL) { perror("my_write fopen"); return; } Stu s[3]; char buf[50]; for (int i = 0; i < 3; i ) { sprintf(buf, "stu%d%d%d", i, i, i); strcpy(s[i].name, buf); s[i].id = i 1; } //按块写文件 //s 写入文件内容的首地址 //sizeof(Stu) 块数据的大小 //3 块数 写文件的数据大小 sizeof(Stu)*3 //fp 文件指针 //返回值 成功写入文件的块数 int ret = fwrite(s, sizeof(Stu), 3, fp); printf("ret=%d\n", ret);//3 if (fp != NULL) { fclose(fp); fp = NULL; } } void my_fread(char** path) { FILE* fp = fopen(path, "r "); if (fp == NULL) { perror("my_fread fopen"); return; } Stu s[3]; Stu temp;//读三个结构体 fseek(fp, 2*sizeof(Stu), SEEK_SET); //fseek(fp, -1*sizeof(Stu), SEEK_END); int ret = fread(&temp, sizeof(Stu), 1, fp); if (ret==1) { printf("[temp]=%s,%d\n", temp.name, temp.id); } //将文件光标移动到开始位置 //fseek(fp, 0, SEEK_SET); rewind(fp);//光标置首 //按块读文件 //s 放文件内容首地址 //sizeof(Stu) 块数据的大小 //3 块数 读文件的数据大小 sizeof(Stu)*3 //fp 文件指针 //返回值 成功读出文件的块数 ret = fread(s, sizeof(Stu), 3, fp); printf("ret=%d\n", ret);//3 for (int i = 0; i < 3; i ) { printf("%s,%d\n", s[i].name, s[i].id); } if (fp != NULL) { fclose(fp); fp = NULL; } } int main() { my_fwrite("../07.txt"); my_fread("../07.txt"); return 0; }

c语言读取文件字符的行数(C语言文件的随机读写)(4)

打印结果

,