c盘能格式化吗(格式化磁盘后的文件可以恢复吗)
结构体嵌套练习
在这里我们创建一个结构体数组,该数组有三名老师,每名老师又带有三名同学,我们分别给他们赋值,最后根据老师的名字进行降序排列。
#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赋值为NULLvoid 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:%dn", 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;}
打印结果
按照字符读写文件fgetc、fputc的使用
fgetc():
int fgetc(FILE *stream)
参数:
stream — 这是指向 FILE 对象的指针,该 FILE 对象标识了要在上面执行操作的流。
返回值
该函数以无符号 char 强制转换为 int 的形式返回读取的字符,如果到达文件末尾或发生读错误,则返回 EOF。
fputc():
int fputc(int char, FILE *stream)
参数:
char — 这是要被写入的字符。该字符以其对应的 int 值进行传递。stream — 这是指向 FILE 对象的指针,该 FILE 对象标识了要被写入字符的流。
返回值:
如果没有发生错误,则返回被写入的字符。如果发生错误,则返回 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("%sn", 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=%cn", 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)str — 这是指向一个字符数组的指针,该数组存储了要读取的字符串。n — 这是要读取的最大字符数(包括最后的空字符)。通常是使用以 str 传递的数组长度。stream — 这是指向 FILE 对象的指针,该 FILE 对象标识了要从中读取字符的流。
fputs():
int fputs(const char *str, FILE *stream)str — 这是一个数组,包含了要写入的以空字符终止的字符序列。stream — 这是指向 FILE 对象的指针,该 FILE 对象标识了要被写入字符串的流。
#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[] = { "aaan","bbbn","cccn" }; for (int i = 0; i < strlen(buf); i++) { //返回值是成功写入文件个数,成功返回0,失败非0 int len = fputs(buf[i], fp); printf("len=%dn", 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=%sn", 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;}
打印结果
按照块读写文件fread、fwrite
fread():
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)ptr — 这是指向带有最小尺寸 size*nmemb 字节的内存块的指针。size — 这是要读取的每个元素的大小,以字节为单位。nmemb — 这是元素的个数,每个元素的大小为 size 字节。stream — 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流。返回值:
成功读取的元素总数会以 size_t 对象返回,size_t 对象是一个整型数据类型。如果总数与 nmemb 参数不同,则可能发生了一个错误或者到达了文件末尾
fwrite():
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)ptr — 这是指向要被写入的元素数组的指针。size — 这是要被写入的每个元素的大小,以字节为单位。nmemb — 这是元素的个数,每个元素的大小为 size 字节。stream — 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输出流。返回值:
如果成功,该函数返回一个 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=%dn", 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=%dn", ret);//3 for (int i = 0; i < 3; i++) { printf("%s,%dn", 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;}
打印结果
按照格式化读写文件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%dn", 001); //fprintf(stdout, "hello world%dn", 001);//实际结果与上相同 fprintf(fp, "%d %d %dn", 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%dn", 001); //fprintf(stdout, "hello world%dn", 001);//实际结果与上相同 int a = 0; int b = 0; int c = 0; fscanf(fp, "%d %d %dn", &a,&b,&c); printf("a=%d,b=%d,c=%dn", 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)stream — 这是指向 FILE 对象的指针,该 FILE 对象标识了流。offset — 这是相对 whence 的偏移量,以字节为单位。whence — 这是表示开始添加偏移 offset 的位置。它一般指定为下列常量之一:
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=%dn", 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,%dn", 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=%dn", ret);//3 for (int i = 0; i < 3; i++) { printf("%s,%dn", 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;}
打印结果
如发现本站有涉嫌抄袭侵权/违法违规等内容,请<举报!一经查实,本站将立刻删除。