[comp.lang.c] Array Problems

duchow@watnxt3.ucr.edu (John Duchowski) (05/26/91)

Hi,

     I am a bit of a novice at this, so this is probably something simple,
nevertheless I can't seem to be able to get around it.  The program below
reads a file which looks like this:

	PellinBroca 770-810 1900V 20mW 3sINT 
	10cmFL-617OL
	 108
	 2
	 0
	 7.7448E-12
	 10
	 7.8324E-12
	 20
	 9.425E-12
	 30
	 8.753E-12
	 40
	 1.0755E-11
         .
         .

and converts it to a file which looks like this:

	PellinBroca 770-810 1900V 20mW 3sINT 
	10cmFL-617OL 
	    0.0000         0.0005
	   10.0000         0.0005
	   20.0000         0.0006
	   30.0000         0.0005
	   40.0000         0.0007
             .
             .

(normalized here, but a scaling factor can be used as well).  Anyway, the
main problem is that in its present form (please see below) it runs ok on
a NeXT ('030, Mach 2.0, cc compiler) and on a Vax (8820, VMS 5.4, Vax C)
but not on my AT (DR DOS 5.0, bc++).  At home the array registers seem to
be out of step, i.e., an extra point gets written in before the 0th point.
I have tried both: for(i=1; i<=n; i++) and for(i=0, i<n, i++) and only
the former (less elegant) version works.  I don't understand why neither
the Vax nor the NeXT object to this, but my AT does.  The second, lesser
problem is that of elegance.  I can't seem to get around the following
warnings:

Borland C++  Version 2.0 Copyright (c) 1991 Borland International
hp2plot.c:
Warning hp2plot.c 73: Parameter 'argc' is never used in function input
Warning hp2plot.c 127: Parameter 'argc' is never used in function output
Warning hp2plot.c 127: Function should return a value in function output

When I remove argc from output, the file name then look weird (some binary
bits or something).  When I try return(0) in output the values actually
get zeroed and when I declare output as void, I get a domain error (I think).

Could anyone please shed more light on this ?  Any hints, comments, etc.,
will be greatly appreciated.  Thank you !

                            - John Duchowski
----------------------------------------------------------------------------
/* Program hp2plot.c - convert HP900 series 300 files to PC format */
/* Add plotting routine                                            */
/* John K. Duchowski,  May 20, 1991                                */
#include <stdio.h>
#include <math.h>

#define EOL	'\n'

typedef struct {
	char	head[6][20];
} header_struct;

void read_header(fptr, header)
FILE		*fptr;
header_struct	*header;
{
   char  junk[20];
   int   i;
   if(fptr)
   {
     for(i = 0; i < 6; i++)
	fscanf(fptr,"%s", header->head[i]);
     fscanf(fptr,"%s%s",junk,junk);
   }
}

void write_header(fptr, header)
FILE		*fptr;
header_struct	*header;
{
   int   i;
   if(fptr)
   {
     for(i = 0; i < 5; i++)
	fprintf(fptr,"%s ", header->head[i]);

     fprintf(fptr,"\n");
     fprintf(fptr,"%s ",header->head[5]);
     fprintf(fptr,"\n");
   }
}

input(argc, argv, x, y, header)
int			*argc;
char			*argv[];
float			*x;
float			*y;
header_struct		*header;
{
  FILE	*fptr;
  char	c;
  int	i = 1;

  if((fptr = fopen(argv[1], "r")) == NULL)
  {
    fprintf(stderr,"Can't open file %s\n",argv[1]);
    exit(-1);
  }
  read_header(fptr,header);
  printf("\nReading points from the input file %s\n", argv[1]);

  while((c = fgetc(fptr)) != EOF)
  {
    ungetc(c,fptr);
    fscanf(fptr,"%f",&x[i]); 
    fscanf(fptr,"%e",&y[i]); 
    i++;
    while((c = fgetc(fptr)) != EOL);
    c = fgetc(fptr);
  }
  
  printf("\n");
  fclose(fptr);
  return(i);       /* return the number of points read */
}

output(argc, argv, x, y, n, header)
int		*argc;
char		*argv[];
float		*x;
float		*y;
int		n;
header_struct	*header;
{
   FILE *fptr;
   int i, norm;
   float high, scale;

   if((fptr = fopen(argv[2], "w")) == NULL)
   {
     fprintf(stderr,"Can't open file %s\n", argv[2]);
     exit(-1);
   }
   write_header(fptr,header);
   
   printf("\nNormalize (max value = 1.0) ? (yes = 1) ");
   scanf("%d", &norm);
   if(norm == 1)
   {
     high = y[0];
     for(i = 0; i < n; i++)
     {
        if(y[i] > high)
          high = y[i];
     }

     for(i = 0; i < n; i++)
        y[i] = y[i]/high;
   }

   else
   {
     printf("\nEnter the scaling factor: ");
     scanf("%f", &scale);
     
     for(i = 0; i < n; i++)
        y[i] = y[i]*scale;
   }

   printf("\nWriting points to the output file %s\n", argv[2]);

   for(i = 0; i < n; i++)
   {
      fprintf(fptr,"%10.4f     %10.4f\n", x[i], y[i]);
      fflush(fptr);
   }
   fclose(fptr);
}

main(argc, argv)
int	argc;
char	*argv[];
{
   header_struct header;
   float x[5000];
   float y[5000];
   int n;

   if(argc != 3)
   {
     fprintf(stderr,"Usage: %s <infile> <outfile> \n", argv[0]);
     exit(-1);
   }

   n = input(argc, argv, x, y, &header);
   printf("%d points read\n",n);

   output(argc, argv, x, y, n, &header);
   return(0);
}

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (05/27/91)

This is not the real problem, but in article <14724@ucrmath.ucr.edu>,
duchow@watnxt3.ucr.edu (John Duchowski) writes:

> input(argc, argv, x, y, header)
> int			*argc;			<------
> char			*argv[];
  ...
> output(argc, argv, x, y, n, header)
> int		*argc;				<------
> char		*argv[];
  ...
> main(argc, argv)
> int	argc;
> char	*argv[];
> {
  ...
>    n = input(argc, argv, x, y, &header);	<------
 ...           ^^^^
>    output(argc, argv, x, y, n, &header);	<------
            ^^^^

That suggests that the functions should have been declared
	void input(argc, argv, x, y, header)
	    int argc;
	    char *argv[];
	    ...
	void output(argc, argv, x, y, n, header)
	    int argc;
	    char *argv[];
	    ...
and that there may be other problems lurking around that 'lint'
(surely the NeXt has 'lint'?) would catch.

Myself, I always write "char **argv;"; C doesn't really understand
arrays as parameters, and using a notation that suggests that it does
will only get you in trouble.
 
-- 
I rejoiced that at least So-and-So could spell "hierarchical",
but the _real_ explanation was that he couldn't spell "heir".	-me