#include #include #include #include /******************************************************************* * matrix_transpose * * Simple program to invert a matrix found in the and write * the result into . need not to exist(it is * created if necessary). is not created or touched in any * way in the event of an input error. * * and have the following format: * integer rows and columns on first line, separated by white space * one row on each subsequent line, column entries separated by * white space. ******************************************************************/ /* #define MIN(a,b) ((a)<(b))?(a):(b) */ #define MAX_ROWS 256 #define MAX_COLS 256 #define MAX_LINESIZE 30*256 /* Input lines Long enough to inlude 256 doubles + delimeters + a newline*/ char line[MAX_LINESIZE + 1]; /* input buffer */ static struct matrix_s { int rows, cols; double data[MAX_ROWS][MAX_COLS]; } the_matrix_s; /* matrix holding area */ typedef struct matrix_s *matrix_t; void read_matrix(matrix_t matrix, FILE *infile, char *infilename) { int i, j, ret; char *startp, *endp; if (fgets(line, MAX_LINESIZE, infile) == NULL) { fprintf(stderr, "Cannot read dimensions from %s.\n", infilename); fprintf(stderr, "First line of input file must be .\n"); exit(-1); } ret = sscanf(line, "%d %d", &matrix->rows, &matrix->cols); if (ret != 2) { fprintf(stderr, "Cannot read dimensions from %s.\n", infilename); fprintf(stderr, "First line of input file must be .\n"); exit(-1); } if ((matrix->rows > MAX_ROWS) || (matrix->cols >MAX_COLS)) { fprintf(stderr, "Maximum number of rows/columns: %d/%d.\n", MAX_ROWS, MAX_COLS); exit(-1); /* Could do this to truncate oversized matrices. But interferes with error checking. matrix->rows = MIN(matrix.rows, MAX_ROWS); matrix->cols = MIN(matrix.cols, MAX_COLS); */ } if ((matrix->rows < 0) || (matrix->cols < 0)) { fprintf(stderr, "rows/columns must not be negative: %d/%d.\n", matrix->rows, matrix->cols); exit(-1); } for (i = 0; i < matrix->rows; i++) { if (fgets(line, MAX_LINESIZE, infile) == NULL) { fprintf(stderr, "Error reading line %d from %s\n", i, infilename); exit(-1); } for (j = 0, startp = endp = line; jcols; j++, startp=endp) { matrix->data[i][j] = strtod(startp, &endp); /* ret = fscanf(infile, "%lf", &matrix->data[i][j]);*/ /* if (ret != 1) { */ if (endp == startp) { fprintf(stderr, "Unable to read matrix element [%d, %d].\n", i, j); exit(-1); } } if (sscanf(endp, " %*s") != EOF) { fprintf(stderr, "Too much information in row %d\n", i); exit(-1); } } if (fgets(line, MAX_LINESIZE, infile) != NULL) { fprintf(stderr, "Too many lines on input\n"); exit(-1); } } /* read_matrix */ int main (int argc, char* argv[]) { FILE *infile, *outfile; char *infilename, *outfilename; int i, j, ret; matrix_t matrix = &the_matrix_s; if (argc != 3) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(-1); } if (strcmp(argv[1], "-") == 0) { infile = stdin; infilename = ""; } else { infile = fopen(argv[1], "r"); infilename = argv[1]; } if (!infile) { fprintf(stderr, "%s: Cannot open %s: %s\n", argv[0], argv[1], strerror(errno)); exit(-1); } read_matrix(matrix, infile, infilename); fclose(infile); /* no harm in closing stdin if we're reading it */ if (strcmp(argv[2], "-") == 0) { outfile = stdout; outfilename = ""; } else { outfile = fopen(argv[2], "w"); outfilename = argv[2]; } if (!outfile) { fprintf(stderr, "%s: Cannot open %s: %s\n", argv[0], argv[2], strerror(errno)); exit(-1); } /* Transpose the matrix on output. */ ret = fprintf(outfile, "%d %d\n", matrix->cols, matrix->rows); if (ret < 0) { fprintf(stderr, "Unable to write output\n"); exit(-1); } for (i=0; i < matrix->cols; i++) { for (j=0; j < matrix->rows; j++) fprintf(outfile, "%f ", matrix->data[j][i]); fprintf(outfile, "\n"); } fclose(outfile); /* no harm closing stdout if we're writing it */ return 0; } /* main */