📄 matrixio.c
字号:
/**************************************************************************
**
** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
**
** Meschach Library
**
** This Meschach Library is provided "as is" without any express
** or implied warranty of any kind with respect to this software.
** In particular the authors shall not be liable for any direct,
** indirect, special, incidental or consequential damages arising
** in any way from use of the software.
**
** Everyone is granted permission to copy, modify and redistribute this
** Meschach Library, provided:
** 1. All copies contain this copyright notice.
** 2. All modified copies shall carry a notice stating who
** made the last modification and the date of such modification.
** 3. No charge is made for this software or works derived from it.
** This clause shall not be construed as constraining other software
** distributed on the same medium as this software, nor is a
** distribution fee considered a charge.
**
***************************************************************************/
/* 1.6 matrixio.c 11/25/87 */
#include <stdio.h>
#include <ctype.h>
#include "matrix.h"
static char rcsid[] = "$Id: matrixio.c,v 1.4 1994/01/13 05:31:10 des Exp $";
/* local variables */
static char line[MAXLINE];
/**************************************************************************
Input routines
**************************************************************************/
/* skipjunk -- skips white spaces and strings of the form #....\n
Here .... is a comment string */
#ifndef ANSI_C
int skipjunk(fp)
FILE *fp;
#else
int skipjunk(FILE *fp)
#endif
{
int c;
for ( ; ; ) /* forever do... */
{
/* skip blanks */
do
c = getc(fp);
while ( isspace(c) );
/* skip comments (if any) */
if ( c == '#' )
/* yes it is a comment (line) */
while ( (c=getc(fp)) != '\n' )
;
else
{
ungetc(c,fp);
break;
}
}
return 0;
}
/* m_finput -- input matrix
-- input from a terminal is handled interactively
-- batch/file input has the same format as produced by m_foutput
except that whitespace and comments ("#..\n") are skipped
-- returns a, which is created if a == NULL on entry */
#ifndef ANSI_C
MAT *m_finput(fp,a)
FILE *fp;
MAT *a;
#else
MAT *m_finput(FILE *fp, MAT *a)
#endif
{
MAT *im_finput(),*bm_finput();
if ( isatty(fileno(fp)) )
return im_finput(fp,a);
else
return bm_finput(fp,a);
}
/* im_finput -- interactive input of matrix */
#ifndef ANSI_C
MAT *im_finput(fp,mat)
FILE *fp;
MAT *mat;
#else
MAT *im_finput(FILE *fp,MAT *mat)
#endif
{
char c;
unsigned int i, j, m, n, dynamic;
/* dynamic set to TRUE if memory allocated here */
/* get matrix size */
if ( mat != (MAT *)NULL && mat->m<MAXDIM && mat->n<MAXDIM )
{ m = mat->m; n = mat->n; dynamic = FALSE; }
else
{
dynamic = TRUE;
do
{
fprintf(stderr,"Matrix: rows cols:");
if ( fgets(line,MAXLINE,fp)==NULL )
error(E_INPUT,"im_finput");
} while ( sscanf(line,"%u%u",&m,&n)<2 || m>MAXDIM || n>MAXDIM );
mat = m_get(m,n);
}
/* input elements */
for ( i=0; i<m; i++ )
{
redo:
fprintf(stderr,"row %u:\n",i);
for ( j=0; j<n; j++ )
do
{
redo2:
fprintf(stderr,"entry (%u,%u): ",i,j);
if ( !dynamic )
fprintf(stderr,"old %14.9g new: ",
mat->me[i][j]);
if ( fgets(line,MAXLINE,fp)==NULL )
error(E_INPUT,"im_finput");
if ( (*line == 'b' || *line == 'B') && j > 0 )
{ j--; dynamic = FALSE; goto redo2; }
if ( (*line == 'f' || *line == 'F') && j < n-1 )
{ j++; dynamic = FALSE; goto redo2; }
#if REAL == DOUBLE
} while ( *line=='\0' || sscanf(line,"%lf",&mat->me[i][j])<1 );
#elif REAL == FLOAT
} while ( *line=='\0' || sscanf(line,"%f",&mat->me[i][j])<1 );
#endif
fprintf(stderr,"Continue: ");
fscanf(fp,"%c",&c);
if ( c == 'n' || c == 'N' )
{ dynamic = FALSE; goto redo; }
if ( (c == 'b' || c == 'B') /* && i > 0 */ )
{ if ( i > 0 )
i--;
dynamic = FALSE; goto redo;
}
}
return (mat);
}
/* bm_finput -- batch-file input of matrix */
#ifndef ANSI_C
MAT *bm_finput(fp,mat)
FILE *fp;
MAT *mat;
#else
MAT *bm_finput(FILE *fp,MAT *mat)
#endif
{
unsigned int i,j,m,n,dummy;
int io_code;
/* get dimension */
skipjunk(fp);
if ((io_code=fscanf(fp," Matrix: %u by %u",&m,&n)) < 2 ||
m>MAXDIM || n>MAXDIM )
error(io_code==EOF ? E_EOF : E_FORMAT,"bm_finput");
/* allocate memory if necessary */
if ( mat==(MAT *)NULL )
mat = m_resize(mat,m,n);
/* get entries */
for ( i=0; i<m; i++ )
{
skipjunk(fp);
if ( fscanf(fp," row %u:",&dummy) < 1 )
error(E_FORMAT,"bm_finput");
for ( j=0; j<n; j++ )
#if REAL == DOUBLE
if ((io_code=fscanf(fp,"%lf",&mat->me[i][j])) < 1 )
#elif REAL == FLOAT
if ((io_code=fscanf(fp,"%f",&mat->me[i][j])) < 1 )
#endif
error(io_code==EOF ? 7 : 6,"bm_finput");
}
return (mat);
}
/* px_finput -- inputs permutation from file/stream fp
-- input from a terminal is handled interactively
-- batch/file input has the same format as produced by px_foutput
except that whitespace and comments ("#..\n") are skipped
-- returns px, which is created if px == NULL on entry */
#ifndef ANSI_C
PERM *px_finput(fp,px)
FILE *fp;
PERM *px;
#else
PERM *px_finput(FILE *fp,PERM *px)
#endif
{
PERM *ipx_finput(),*bpx_finput();
if ( isatty(fileno(fp)) )
return ipx_finput(fp,px);
else
return bpx_finput(fp,px);
}
/* ipx_finput -- interactive input of permutation */
#ifndef ANSI_C
PERM *ipx_finput(fp,px)
FILE *fp;
PERM *px;
#else
PERM *ipx_finput(FILE *fp,PERM *px)
#endif
{
unsigned int i,j,size,dynamic; /* dynamic set if memory allocated here */
unsigned int entry,ok;
/* get permutation size */
if ( px!=(PERM *)NULL && px->size<MAXDIM )
{ size = px->size; dynamic = FALSE; }
else
{
dynamic = TRUE;
do
{
fprintf(stderr,"Permutation: size: ");
if ( fgets(line,MAXLINE,fp)==NULL )
error(E_INPUT,"ipx_finput");
} while ( sscanf(line,"%u",&size)<1 || size>MAXDIM );
px = px_get(size);
}
/* get entries */
i = 0;
while ( i<size )
{
/* input entry */
do
{
redo:
fprintf(stderr,"entry %u: ",i);
if ( !dynamic )
fprintf(stderr,"old: %u->%u new: ",
i,px->pe[i]);
if ( fgets(line,MAXLINE,fp)==NULL )
error(E_INPUT,"ipx_finput");
if ( (*line == 'b' || *line == 'B') && i > 0 )
{ i--; dynamic = FALSE; goto redo; }
} while ( *line=='\0' || sscanf(line,"%u",&entry) < 1 );
/* check entry */
ok = (entry < size);
for ( j=0; j<i; j++ )
ok &= (entry != px->pe[j]);
if ( ok )
{
px->pe[i] = entry;
i++;
}
}
return (px);
}
/* bpx_finput -- batch-file input of permutation */
#ifndef ANSI_C
PERM *bpx_finput(fp,px)
FILE *fp;
PERM *px;
#else
PERM *bpx_finput(FILE *fp,PERM *px)
#endif
{
unsigned int i,j,size,entry,ok;
int io_code;
/* get size of permutation */
skipjunk(fp);
if ((io_code=fscanf(fp," Permutation: size:%u",&size)) < 1 ||
size>MAXDIM )
error(io_code==EOF ? 7 : 6,"bpx_finput");
/* allocate memory if necessary */
if ( px==(PERM *)NULL || px->size<size )
px = px_resize(px,size);
/* get entries */
skipjunk(fp);
i = 0;
while ( i<size )
{
/* input entry */
if ((io_code=fscanf(fp,"%*u -> %u",&entry)) < 1 )
error(io_code==EOF ? 7 : 6,"bpx_finput");
/* check entry */
ok = (entry < size);
for ( j=0; j<i; j++ )
ok &= (entry != px->pe[j]);
if ( ok )
{
px->pe[i] = entry;
i++;
}
else
error(E_BOUNDS,"bpx_finput");
}
return (px);
}
/* v_finput -- inputs vector from file/stream fp
-- input from a terminal is handled interactively
-- batch/file input has the same format as produced by px_foutput
except that whitespace and comments ("#..\n") are skipped
-- returns x, which is created if x == NULL on entry */
#ifndef ANSI_C
VEC *v_finput(fp,x)
FILE *fp;
VEC *x;
#else
VEC *v_finput(FILE *fp,VEC *x)
#endif
{
VEC *ifin_vec(),*bfin_vec();
if ( isatty(fileno(fp)) )
return ifin_vec(fp,x);
else
return bfin_vec(fp,x);
}
/* ifin_vec -- interactive input of vector */
#ifndef ANSI_C
VEC *ifin_vec(fp,vec)
FILE *fp;
VEC *vec;
#else
VEC *ifin_vec(FILE *fp,VEC *vec)
#endif
{
unsigned int i,dim,dynamic; /* dynamic set if memory allocated here */
/* get vector dimension */
if ( vec != (VEC *)NULL && vec->dim<MAXDIM )
{ dim = vec->dim; dynamic = FALSE; }
else
{
dynamic = TRUE;
do
{
fprintf(stderr,"Vector: dim: ");
if ( fgets(line,MAXLINE,fp)==NULL )
error(E_INPUT,"ifin_vec");
} while ( sscanf(line,"%u",&dim)<1 || dim>MAXDIM );
vec = v_get(dim);
}
/* input elements */
for ( i=0; i<dim; i++ )
do
{
redo:
fprintf(stderr,"entry %u: ",i);
if ( !dynamic )
fprintf(stderr,"old %14.9g new: ",vec->ve[i]);
if ( fgets(line,MAXLINE,fp)==NULL )
error(E_INPUT,"ifin_vec");
if ( (*line == 'b' || *line == 'B') && i > 0 )
{ i--; dynamic = FALSE; goto redo; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -