目标:
掌握指针和结构、文件的结合使用。掌握形参与实参首先通过读书,掌握c语言文本文件的基本概念和基本操作。熟悉文本文件的读写及fopen/fclose,fscanf/fprintf等函数。 上机练习1:将几个数字及字符串写入文件。读出并显示。通过读书,掌握结构的基本概念;学习和实践结构数组,结构指针概念。 上机练习2:将矩阵表示为结构,成员包括:矩阵行数,列数,及指向矩阵具体元素的指针;然后重做第一课练习。
作业:
使用读写文件的矩阵乘法
要求:
读出指定文本文件中各矩阵,计算多矩阵相乘后结果,并将结果写入另一文本文件中。 文件名任意;如输入文件:input.txt; 输出文件out.txt 输入文件格式:将多个矩阵记录在文件中,多个矩阵以空行分隔。类似: 1 3 2 2 5 4
3 8 12 (上述文件包括2个矩阵,分别为2*3和3*1的)(提示:对于多矩阵,可使用结构数组/结构指针)
#include #include #include using namespace std; struct mat /*结构体,包含每个矩阵自身的信息,以及下一个矩阵的存储位置*/ { int rows = 0; int columns = 0; int **a = NULL; struct mat *next = NULL; }result; void input() /*向矩阵中输入数据*/ { int i, j, num = 0, flag = 0; char ch; struct mat *p=NULL; FILE *fp; /*打开文件*/ if ((fp = fopen("input.txt", "r")) == NULL){ cout << "Error."; exit(1); } p = result.next; while (p != NULL){ /*开括矩阵空间*/ if ((p->a = (int **)malloc(p->rows*sizeof(int *))) == NULL){ cout << "ERROR!"; exit(1); } for (i = 0; i < p->rows; i++) if ((p->a[i] = (int *)malloc(p->columns*sizeof(int))) == NULL){ cout << "ERROR!"; exit(1); } for (i = 0; i < p->rows; i++) for (j = 0; j < p->columns; j++){ while (1){ ch = fgetc(fp); /*将数值记录下来*/ if (ch >= '0' && ch <= '9'){ num = num * 10 + (int)(ch - '0'); flag = 0; } else{ if (ch == 10) flag++; if (flag == 2){ flag = 0; continue; } p->a[i][j] = num; num = 0; break; } } } p = p->next; } fclose(fp); /*创建存结果的矩阵*/ if ((result.a = (int **)malloc(result.rows*sizeof(int *))) == NULL){ cout << "ERROR!"; exit(1); } for (i = 0; i < result.rows; i++) if ((result.a[i] = (int *)malloc(result.columns*sizeof(int))) == NULL){ cout << "ERROR!"; exit(1); } } /*释放空间*/ void freespace() { struct mat *p1 = NULL, *p2 = NULL; int i; p1 = result.next; while (p1!=NULL){ p2 = p1; p1 = p1->next; for (i = 0; i < p2->rows; i++) free(p2->a[i]); free(p2->a); free(p2); } } void calculate() /*计算矩阵乘法*/ { struct mat *p = NULL, temp; int i, j, k; p = result.next; for (i = 0; i < p->rows; i++) /*第一个矩阵可以直接把数据给result矩阵*/ for (j = 0; j < p->columns; j++) result.a[i][j] = p->a[i][j]; result.rows = p->rows; /*记录现在的矩阵的行列数*/ result.columns = p->columns; p=p->next; /*创建一个临时矩阵,用于计算*/ if ((temp.a = (int **)malloc(result.rows*sizeof(int *))) == NULL){ cout << "ERROR!"; exit(1); } for (i = 0; i < result.rows; i++) if ((temp.a[i] = (int *)malloc(result.columns*sizeof(int))) == NULL){ cout << "ERROR!"; exit(1); } while (p != NULL){ for (i = 0; i < result.rows; i++) /*把result矩阵里的数给临时矩阵,并将result矩阵清零*/ for (j = 0; j < result.columns; j++){ temp.a[i][j] = result.a[i][j]; result.a[i][j] = 0; } temp.rows = result.rows; temp.columns = result.columns; for (i = 0; i < temp.rows; i++) /*进行临时矩阵和当前矩阵的乘法运算,将结果保存在result矩阵*/ for (j = 0; j < p->columns; j++){ for (k = 0; k < temp.columns; k++) result.a[i][j] += temp.a[i][k] * p->a[k][j]; } result.columns = p->columns; /*记录当前的矩阵列数,行数则不变*/ p = p->next; } } int main(void) { FILE *fp; char ch; int flag = 0, r = 0, c = 0; struct mat *p = NULL, *temp = NULL; p = &result; /*打开文件*/ if ((fp = fopen("input.txt", "r")) == NULL){ cout << "Error."; exit(1); } do /*一直读到文件结束为止*/ { ch = fgetc(fp); if (ch >= '0' && ch <= '9') /*记录有多少个元素*/{ flag = 0; continue; } r++; /*记录连续的换行符的个数,若有连续两个换行符,说明下面是一个新的矩阵*/ if (ch == 10){ flag++; c++; } /*将每个矩阵的行列数记录下来*/ if (flag == 2 || ch == EOF){ temp = (struct mat*)malloc(sizeof(struct mat)); temp->rows = c + 1 - flag; temp->columns = (r - 1) / temp->rows; temp->next = NULL; if (temp->rows > result.rows) result.rows = temp->rows; if (temp->columns > result.columns) result.columns = temp->columns; p->next = temp; p = p->next; flag = 0; c = 0; r = 0; } } while (ch != EOF); fclose(fp); input(); calculate(); /*打开文件*/ if ((fp = fopen("out.txt", "w")) == NULL){ cout << "Error."; exit(1); } /*输出运算结果*/ for (int i = 0; i < result.rows; i++){ for (int j = 0; j < result.columns; j++) fprintf(fp,"%d\t",result.a[i][j]); fprintf(fp,"\n"); } fclose(fp); freespace(); return 0; } /* 本程序要求input.txt具有如下格式: 1 3 2(每行最后一个数后面的字符为换行符) 2 5 4 (矩阵之间空一行,且这一行只有一个换行符) 3 8 12 (文件结束标志“EOF”必须在最后一个数的下一行,且这一行只有这一个字符) */
