[comp.sys.amiga] C problems

armhold@topaz.rutgers.edu (George Armhold) (05/30/89)

I started using my C compiler today (Manx Aztec V3.6a), and I'm really
frustrated with I/O. I have the K&R book, _Understanding C_ by Bruce
Hunter, as well as the documentation that came with Manx. All three of
them left me bewildered with the various file I/O conventions. There's
open, fopen, creat, etc... Which do I use when? What about writing to
the console? Can anyone recommend a GOOD book that explains the
various methods of I/O and also points out differences between
"standard" and "machine specific"? 

Also, here's some source I tried today. What I'm trying to do is
simply copy one file to another. When I compile it, I get error 125
which means "too many subscripts or indirection on integer". It occurs
wherever I mention argv[x].

#include <stdio.h>
main(argc, argv)
{
	int c;
	FILE *fp1, *fp2;
		       	
	if ((fp1=fopen(argv[1], "r"))==NULL) {
		printf("Can't open %s", argv[1]);
		exit();
		}

	if ((fp2=fopen(argv[2], "w"))==NULL) {
		printf("Can't open %s", argv[2]);
		exit();
		}
	
	while ((c=getc(fp1)!=EOF)) 
		putc(fp2);

}

Thanks
-George

deven@rpi.edu (Deven Corzine) (05/30/89)

In article <May.29.21.40.18.1989.8866@topaz.rutgers.edu> armhold@topaz.rutgers.edu (George Armhold) writes:

   I started using my C compiler today (Manx Aztec V3.6a), and I'm really
   frustrated with I/O.

Poor guy...  you'll surely be baffled by Amiga Exec I/O...

   Also, here's some source I tried today. What I'm trying to do is
   simply copy one file to another. When I compile it, I get error 125
   which means "too many subscripts or indirection on integer". It occurs
   wherever I mention argv[x].

   #include <stdio.h>
   main(argc, argv)
   {
   [...]

This error has nothing to do with the I/O; you never declared what the
parameters rto main were, so the compiler assumed integer for both.
argc is an integer, but argv is a char **.  You need to add a line
after main(argc,argv) but BEFORE the "{" which reads "char **argv;" or
"char *argv[];" (take your pick; they mean the same.) and you *should*
add right before it "int argc;" but you don't need to, since the
compiler will assume it.

It thought argv was an integer, and argv[x] was the indirection on
integer causing the error.

Deven
--
shadow@[128.113.10.2]   <shadow@pawl.rpi.edu> Deven T. Corzine (518) 272-5847
shadow@[128.113.10.201] <shadow@acm.rpi.edu>  2346 15th St.    Pi-Rho America
deven@rpitsmts.bitnet   <userfxb6@rpitsmts>   Troy, NY 12180-2306  <<tionen>>
"Simple things should be simple and complex things should be possible." - A.K.

armhold@topaz.rutgers.edu (George Armhold) (05/30/89)

Thanks to the many people who responded to my cries for help with C.
Only a few hours after I posted, I receieved around 20 replies! Now I
feel silly, of course declaring argv and argc was the problem!
Thanks again.

-George

stephen@hpdml93.HP.COM (Stephen Holmstead) (05/30/89)

>There's open, fopen, creat, etc... Which do I use when? What about writing to
>the console? Can anyone recommend a GOOD book that explains the
>various methods of I/O and also points out differences between
>"standard" and "machine specific"? 

Briefly, open, creat, write, etc. are lower-level I/O routines.  Each
process 'n' bytes of raw data.  fopen, fprintf, fclose, etc. are higher
level routines.  They will process "formatted" data.  For someone new to
'C', I recommend that you use the 'f..' commands (they are easier to
produce the desired result but are slower).  I assume that you have the
complete documentation on these, so I will only mention a few of the
command names...

fopen() -- opens a file and returns a file handle.
fclose() -- closes a file.
fprintf() -- just like 'printf' except to a file (formatted print).
fputs() -- put a string to a file.
fputc() -- put a character to a file.
fgets() -- get a string from a file.
fgetc() -- get a character from a file.
fscanf() -- formatted read (just like 'scanf').

>Also, here's some source I tried today. What I'm trying to do is
>simply copy one file to another. When I compile it, I get error 125
>which means "too many subscripts or indirection on integer". It occurs
>wherever I mention argv[x].
>
>#include <stdio.h>
>main(argc, argv)
*************
PROBLEM:  You forgot to tell the compiler the type of the input paramters.
          The compiler assumed that both were 'int' because you didn't
	  specify otherwise.
int argc;
char *argv[];
*************
>{
>	int c;
>	FILE *fp1, *fp2;
>		       	
>	if ((fp1=fopen(argv[1], "r"))==NULL) {
>		printf("Can't open %s", argv[1]);
>		exit();
>		}
>
>	if ((fp2=fopen(argv[2], "w"))==NULL) {
>		printf("Can't open %s", argv[2]);
>		exit();
>		}
>	
>	while ((c=getc(fp1)!=EOF)) 
>		putc(fp2);
>
>}

Just a couple of notes:
1. 'exit' requires a parameter which it returns to the operating system.
   Most people will return a negative number to indicate an error has
   occurred.  (format:  exit(-1);)
2. It is also common practice to make sure that there are at least
   enough arguments given before you assume they exist:
   if (argc<3)
   {
      printf ("Not enough arguments; format: %s <input_file> <output_file>\n",
              argv[0]);
      exit(-1);
   }

Otherwise, the code looks good.  Have fun with 'C'.

name:    Stephen Holmstead
phone:   (208) 323-2840
uucp:    hplabs!hpdmlge!stephen
uxmail:  stephen@hpdmlge
usmail:  Hewlett-Packard
         Disk Memory Division
         11413 Chinden Blvd
         Boise, ID 83714

grwalter@watmath.waterloo.edu (Fred Walter) (05/31/89)

In article <DEVEN.89May30033457@daniel.rpi.edu> deven@rpi.edu (Deven Corzine) writes:
>In article <May.29.21.40.18.1989.8866@topaz.rutgers.edu> armhold@topaz.rutgers.edu (George Armhold) writes:
>>  I started using my C compiler today (Manx Aztec V3.6a), and I'm really
>>  frustrated with I/O.

>argc is an integer, but argv is a char **.  You need to add a line
>after main(argc,argv) but BEFORE the "{" which reads "char **argv;" or
>"char *argv[];" (take your pick; they mean the same.) and you *should*
>add right before it "int argc;"

As well, the following code segment has a problem...

  	while ((c=getc(fp1)!=EOF)) 
  		putc(fp2);
                ^^^^^^^^^^

You really want to be using putc(c, fp2). (Not to mention adding spaces
would increase the readability of your code IMHO).

	fred

Yuklung_Morris_Ng@cup.portal.com (05/31/89)

You haven't define the type of argc and argv on main().  Remember, main() is a
a function, not a particular program like Pascal.
 
Try this:
 
main(argc,argv)
int argc;
char *argv[];
{
	......;
}
 
				- Morris

doug@xdos.UUCP (Doug Merritt) (05/31/89)

In article <May.29.21.40.18.1989.8866@topaz.rutgers.edu> armhold@topaz.rutgers.edu (George Armhold) writes:
>
>Also, here's some source I tried today. What I'm trying to do is
>simply copy one file to another. When I compile it, I get error 125
>which means "too many subscripts or indirection on integer". It occurs
>wherever I mention argv[x].

Oh well, I may as well join the hundreds of others who will all point out
the same problems. I usually resist but I feel like burning bandwidth
for once:

>main(argc, argv)
>{

You need to declare the parameters here, like for instance:
	main(argc, argv)
		int	argc;
		char	**argv;

>	while ((c=getc(fp1)!=EOF)) 
>		putc(fp2);

There are two problems here...one is that the while() is misparenthesized,
it should be:
>	while ((c=getc(fp1)) != EOF) 

As written it was doing (c = (getc(fp1) != EOF)), which always assigns
either a zero or a one to 'c'.

Second, you're not giving the right parameters, 'c' is missing from
the call:
		putc(c, fp2);

These are all pretty obvious bugs, so I suspect that your original
frustration in not being sure which functions to use in the first place
became a problem in itself. Pirsig called this a "gumption trap" in
"Zen and the Art of Motorcycle Maintenence". The recommended cure is
to stop, cool off, relax, and then go back to what you were doing.

For various reasons (style, portability, forming bug-avoiding habits)
you should also close the files before exiting, and also call exit
explicitly:
	fclose(fp1);
	fclose(fp2);
	exit(0);

The explicit exit provides a clean return code so that your programs
could be used in your 'make' scripts.

For the same reason, your error exits should give a non-zero exit code:
	if (...open fails...)
		exit(1);
Or on the Amiga, perhaps:
		exit(10);
	
Programming in C is fun once you get used to it.
	Doug
-- 
Doug Merritt		{pyramid,apple}!xdos!doug
Member, Crusaders for a Better Tomorrow		Professional Wildeyed Visionary

"Welcome to Mars; now go home!" (Seen on a bumper sticker off Phobos)

dhesi@bsu-cs.bsu.edu (Rahul Dhesi) (05/31/89)

In article <365@xdos.UUCP> doug@xdos.UUCP (Doug Merritt) writes:
>		putc(c, fp2);
and
>	fclose(fp1);

May I respectfully suggest error-checking:

     if (putc(c, fp2) == EOF)
	... handle error ...

And yes, even fclose!

     if (fclose(fp1) == EOF)
	... handle error ...

It seems like overkill, but not detecting a full device is a *very*
common bug in C programs.  (However, a possible optimization is to call
ferror() just once before the output stream is closed instead of
testing the value from putc all the time.)
-- 
Rahul Dhesi <dhesi@bsu-cs.bsu.edu>
UUCP:    ...!{iuvax,pur-ee}!bsu-cs!dhesi
Career change search is on -- ask me for my resume