[comp.lang.c] problem with TC2.0: read

asst-jos@yetti.UUCP (Jonathan) (12/21/89)

 Hi, I am just starting to write a program in C, and I was experimenting
with open(), close(), etc so I could read data in fixed blocks.  I am 
working with Turbo C 2.0 , and the problem is that the program sometimes
works and sometimes doesn't.  I figure every write is 64 bytes, so the file
'database' should always be a multiple of 64.  Unfortunately, this isn't 
always true, sometimes it works, and a write adds all 64 bytes, and every
once in a while it adds a few bytes for the heck of it.  I separated the 
2 programs as reader.c (read the database) and writer.c (add one entry to 
the database) for test purposes. could anyone tell me what I am doing
wrong?? or perhaps what causes TC2.0 to behave strangely.  (I have it
running on an old XT.

The telephone numbers I enter are of the for 5556666, but never longer than 
7 digits. This is meant to be a simplistic example, but the behaviour
of TC is odd. (5556666 gets translated to 71204 or thereabouts)

P.S. It seems to run well on Unix, but I haven't thrown much at it
Any and all help happily accepted, e-mail to.  I will try to reply, 
but my mail usually bounces, so I apologize in advance.

Programs follow:


------   reader.c -------
#include <stdio.h>
#include <fcntl.h>
 
#define NAMESIZE 30
 
struct telentry {
	char last[NAMESIZE];
	char first[NAMESIZE];
	long number;
};


main()
{
	int database;
	struct telentry entry;
 
	if ( (database = open("database", O_RDONLY)) == -1)
	{
		fprintf(stderr, "Unable to open database file\n");
		exit (1);
	}
 
	while ( read( database, &entry, sizeof (struct telentry)) > 0)
		fprintf(stdout, "%s, %s\t%ld\n", entry.last,
					entry.first,entry.number);
 
	if (close(database) == -1)
	{
		fprintf(stderr, "Unable to close database\n");
		exit(1);
	}
}

---- writer.c ----

#include <stdio.h>
#include <fcntl.h>

#define NAMESIZE 30
 
struct telentry {
	char last[NAMESIZE];
	char first[NAMESIZE];
	long number;
};
 
 
main()
{
	struct telentry entry;
	int database, option;
 
	if ((database=open("database",O_WRONLY | O_APPEND | O_CREAT,0666))==-1)
	{
		fprintf(stderr,"Unable to open database\n");
		exit(1);
	}
 
		printf("LAST: "); scanf(" %s", entry.last);
		printf("FIRST: "); scanf(" %s", entry.first);
		printf("NUMBER: "); scanf("%ld", &(entry.number));
		write(database, &entry, sizeof (struct telentry));
 
 
}
-------- end of programs -------
Jeffrey Klein
UUCP: Uunet!utai!utcsri!yunexus!yuyetti!asst-jos
or perhaps guest1@alf  (...sis!alf!guest1)
(416) 783-1883

scott@bbxsda.UUCP (Scott Amspoker) (12/22/89)

In article <352@yetti.UUCP> asst-jos@yetti.UUCP (Research Assistant--Jonathan) writes:
> Hi, I am just starting to write a program in C, and I was experimenting
>with open(), close(), etc so I could read data in fixed blocks.  I am 
>working with Turbo C 2.0 , and the problem is that the program sometimes
>works and sometimes doesn't.  I figure every write is 64 bytes, so the file
>'database' should always be a multiple of 64.  Unfortunately, this isn't 
>always true, sometimes it works, and a write adds all 64 bytes, and every
>once in a while it adds a few bytes for the heck of it.

You got bit by the text mode/binary mode problem.  C compilers running
under MS-DOS must deal with the problem that MS-DOS uses both a
carriage return and a line feed to terminate a line of text.  The I/O
libraries that come with these compilers provide two access modes to
files: text and binary.  Text mode (default) removes the extra carriage
returns when reading and adds carriage returns to line feeds when writing.
Binary mode works the way you are expecting.  You may indicate binary
mode as an option in your open() call.  See the manual for details.


-- 
Scott Amspoker
Basis International, Albuquerque, NM
(505) 345-5232
unmvax.cs.unm.edu!bbx!bbxsda!scott