ptavoly@cs.ruu.nl (Peter Tavoly) (11/30/90)
I've got a weird problem, it'll probably again be nothing, but still, I thought I could bother you with it. Here is my tiny weeny little program (I suggest you read the text below first it's a bit longish but manageable): 1 #include "stdlib.h" 2 #include "stdio.h" 3 4 void load (void); 5 void save (void); 6 void menu (void); 7 8 FILE *in, *out; 9 int y, choice; 10 char ch, line[20][74]; /* max. 20 lines of each max. 74 chars */ 11 12 void main (int argc, char *argv[]) 13 { 14 15 if (argc!=3) { printf ("\n) 1990 by Thomas Tavoly\n\n"); 16 printf ("USAGE: %s input-file output-file\n\n",argv[0]); 17 exit (0); } 18 19 if ((in=fopen (argv[1],"r"))==NULL) { 20 printf ("\nCould not open input-file\n\n"); 21 exit (1); } 22 23 y=0; 24 load(); /* open specified input-file and read stuff */ 25 fclose (in); 26 menu(); /* choose from input supplied by specified input-file */ 27 28 if ((out=fopen (argv[2],"w"))==NULL) { 29 printf ("\nCould not open output-file\n\n"); 30 exit (1); } 31 32 save(); /* output selected item to target-file */ 33 fclose (out); 34 35 } /* main */ 36 37 void load (void) 38 { 39 40 while (!feof(in)) /* <- this is where the trouble starts :( */ 41 { 42 printf ("%2d. ",y+1); /* print line number */ 43 while ((ch=fgetc (in))!='@') /* read until separator encountered */ 44 putchar (ch); /* and output characters one by one */ 45 printf ("\n"); /* next line (if any) */ 46 fgets (line [y],74,in); /* read rest of line for later use */ 47 if (feof(in)) return; 48 y++; 49 } /* while */ 50 } /* load */ 51 52 void save (void) 53 { 54 55 fputs (line [y],out); 56 57 } /* save */ 58 59 void menu (void) 60 { 61 62 do { 63 printf ("\nYour choice: "); 64 scanf ("%d", &choice); 65 } while ((choice < 0) || (choice > y+1)); 66 if (choice == 0) exit (0); 67 68 } /* menu */ Usage: program input_file output_file for example: program s:choice.txt ram:temp.script The program is supposed to read a textfile, formatted in the following way (this is just an arbitrary example): Pack it with PowerPacker 2.3b@SYS:ppacker2.3b Install C compiler in RAM:@execute s:C-startup Start up Moria@execute WB1.3:s/Moria.startup Load the Workbench@loadwb Where all lines are apart on a single line terminated only by one newline as you would get when you typed this in ed. The first part of the line (up to the @) is output to the screen with a line number in front of it, starting with 1. The second part of the line (the separating @ is discarded) is put into a predefined array, for later use. Thus you would see on screen when the program is started up: 1. Pack it with PowerPacker 2.3b 2. Install C compiler in RAM: 3. Start up Moria 4. Load the Workbench The temporary array contains the following: line[0][] = "ppacker2.3b" line[1][] = "execute s:C-startup" line[2][] = "execute WB1.3:s/Moria.startup" line[3][] = "loadwb" Then the following line is displayed: Your choice: Now you can choose from either one of the four above or type a zero (all followed by return) to end the program. According to your choice one of the elements of the array is selected and output to the destination file. E.g. type 3 and the file specified on the command line as the destination file will contain this line: execute WB1.3:s/Moria.startup The program then ends and you can execute the destination file as you would do with a script. (Yes, I heard of more 'stylish' ways of doing this, but I'm not an ace in C yet :) Purpose of this all: to put this program in the startup-sequence and let the user choose one of several programs that can then be run, easily configured through a text file that can be changed by any user without programming knowledge (Later enhancements could include an Intuition interface, as soon as I can get my hands on a good book about Intuition. Can anyone suggest a good one? I know of other (PD?) programs that already do this, does anyone know where I can find them (Fish xxx)? Now the problem is that AztecC 5.0a somehow doesn't recognize the 'feof' in lines 40 and 47. The result of this is that the loop in lines 43-44 will continue forever because the '@' will never be found, since there is none on a new line, however the program keeps printing the character 255 (an y with an umlaut on top) endlessly. I could try to look for a character 255 but this is not a nice way, and suppose that this character appears in your text, (as in Queensryche..:). In case of binaries it is even more likely to appear. What am I forgetting? Is this a 5.0a bug or is there some #include or #define missing? Note, that I did not yet buy the compiler, are later versions any better (5.Xx?) ? How about Lattice? Come on owners, this is your chance to convince a potential buyer :) On a different note: there are now three different views on which compiler is better: 1. Lattice, since a lot of known developers work with it. 2. Manx Aztec, since it is (according to some) more professional (?). 3. It seems Lattice is seen better in the US, but Aztec is used more widely in Europe. What's your view? Please respond by mail, this has been posted through my brother's account as well. I have not much possibility to read mail regularly either.. Thomas Tavoly@connected to an ANCIENT Prime terminal on 1200 bps...:(
peter@sugar.hackercorp.com (Peter da Silva) (12/01/90)
In article <4413@ruuinf.cs.ruu.nl> ptavoly@cs.ruu.nl (Peter Tavoly) writes: > 40 while (!feof(in)) /* <- this is where the trouble starts :( */ > 41 { > 42 printf ("%2d. ",y+1); /* print line number */ > 43 while ((ch=fgetc (in))!='@') /* read until separator encountered */ ^^^^^ What happens if you hit EOF here? After reading the final line you're going to sit in an infinite loop comparing EOF with '@'. The simplest fix is to insert "!feof(in) && " before "(ch=fgetc", but I'd read the whole line into memory and manipulate it there. Not quite as efficient, maybe, but I/O time is likely to dominate in this application. -- Peter da Silva. `-_-' <peter@sugar.hackercorp.com>.
andrew@teslab.lab.OZ (Andrew Phillips) (12/10/90)
In article <4413@ruuinf.cs.ruu.nl> ptavoly@cs.ruu.nl (Peter Tavoly) writes: > 40 while (!feof(in)) /* <- this is where the trouble starts :( */ > 41 { > 43 while ((ch=fgetc (in))!='@') /* read until separator encountered */ > 44 putchar (ch); /* and output characters one by one */ > 46 fgets (line [y],74,in); /* read rest of line for later use */ > 47 if (feof(in)) return; > 49 } /* while */ >Now the problem is that AztecC 5.0a somehow doesn't recognize the 'feof' ... Your trouble is that feof() does not return 1 until after you try reading PAST the end of file. So feof(in) is not true until after you read the first character of the next line (assuming you have a line-feed at the end of the last line of your file). >... however the program keeps printing the character 255 >(an y with an umlaut on top) endlessly. >I could try to look for a character 255 but this is not a nice way, and >suppose that this character appears in your text, (as in Queensryche..:). >In case of binaries it is even more likely to appear. The character 255 comes from fgetc() returning -1 (fgetc returns an INT) to indicate eof (or error) and this being converted to a char when assigned to ch. It would be safer to make ch an int and check for ch being -1 after each call to fgetc(). So I would say that Aztec C feof() is OK, although I haven't bothered to test it. Andrew. -- Andrew Phillips (andrew@teslab.lab.oz.au) Phone +61 (Aust) 2 (Sydney) 289 8712