[comp.lang.c] FILE I/O & SLOW WINDOWS

VC008329%NDSUVM1.BITNET@cunyvm.cuny.EDU (MITCHELL L GRAVES) (02/08/88)

 I have been using Turbo C for anly a few months now and I'm having a couple
of problems with a program I'm writing.

The first problem is that when I save a variable to a file I am having to also
print a 'n'to get to the next line to save my next variable. Problem is, is
when I gets the password variable from the file and do a comparison with the
file variable and the password I type, in it doesn't compare. Here's an example
of how the variables are saved to a file:

        SAVE TO FILE                         RETRIEVE FROM FILE
    file = fopen("main","w");           file = fopen("main","r");
    fputs(title,file);                  fgets(title,sizeof(title),file);
    fprintf(file,'n');                 fprintf(file,'n');
    fputs(password,file);               fgets(password,sizeof(password),file);
    fprintf(file,'n');                 fprintf(file,'n');
    fputs(selpass,file);                fgets(selpass,sizeof(selpass),file);
    fclose(file);                       fclose(file);

Now when I do a string compare it doesn't compare.  Then I printed the password
and used a set of bars (to test) on each side of the string like this:

       printf("Password is: |%s|",&password);

This is what it looks like when I print password:

Password is: |ORANGE
|

It puts the bar on the next line.  Is there anyway to remedy this or even a
better way of doing this.  I sure could use some experienced suggestions.

Problem Two:

I am drawing windows on the screen when  prompting for passwords & things
of that nature.  I can watch the window being drawn (Very Sloooww!).  I heard
there is a way to write the screen to a buffer (or something like that) and
later call it up so I don't have to watch the window being slowly drawn each
time.  Can anyone help me out?

                     A very greatful THANKS in advance!

Mitchell L. Graves (VC008329%NDSUVM1.BITNET@WISCVM.WISC.EDU)

cjc@ulysses.homer.nj.att.com (Chris Calabrese[rs]) (02/09/88)

In article <11678@brl-adm.ARPA>, VC008329%NDSUVM1.BITNET@cunyvm.cuny.EDU writes:
> 
>  I have been using Turbo C for anly a few months now and I'm having a couple
> of problems with a program I'm writing.
> 
> 
>         SAVE TO FILE                         RETRIEVE FROM FILE
>     file = fopen("main","w");           file = fopen("main","r");
>     fputs(title,file);                  fgets(title,sizeof(title),file);
>     fprintf(file,'n');                 fprintf(file,'n');
>     fputs(password,file);               fgets(password,sizeof(password),file);
>     fprintf(file,'n');                 fprintf(file,'n');
>     fputs(selpass,file);                fgets(selpass,sizeof(selpass),file);
>     fclose(file);                       fclose(file);

No, No, No, this is all wrong.

First off, the 'n's are ridiculous.  How about a newline between
variables?  Makes a lot more sense, since this is the delimiter which
fgets uses.

The next problem is that, if title is an array, the sizeof(title) 
part of the code will cause the number of characters to be read in
as had been allocated for (or until a newline), but the fputs(title,file)
part will only write as many characters as come before a '\0' char.
The sizeof code should be avoided for another reason, which is that
title may be a pointer to an array of characters, in which case
sizeof will return the number of bytes in a pointer.

Finally, when using fgets, don't forget to strip the possible \n char
on the end.

The correct code is:

SAVE TO FILE
char title[SIZE];

file = fopen("main","w");
fputs(title,file);
fputc('\n', file);
fputs(password,file);
fputc('\n', file);
fputs(selpass,file);
fputc('\n', file);
fclose(file);

Retrieve

int tmp;

file = fopen("main","r");

fgets(title, SIZE, file);
tmp = strlen(title) -1;
title[tmp] = title[tmp] == '\n' ? '\0' : title[tmp];

fgets(password, SIZE, file);
tmp = strlen(password) -1;
password[tmp] = password[tmp] == '\n' ? '\0' : password[tmp];

fgets(sellpass, SIZE, file);
tmp = strlen(sellpass) -1;
sellpass[tmp] = sellpass[tmp] == '\n' ? '\0' : sellpass[tmp];

fclose(file);


If you don't want to use \n for field seperation, use fscanf to
parse the input line for a field seperator char, or use fixed
length fields with read and write system calls.

	Chris Calabrese
	AT&T Bell Labs
	ulysses!cjc

kk@richp1.UUCP (Ken Konecki) (02/10/88)

In article <11678@brl-adm.ARPA> VC008329%NDSUVM1.BITNET@cunyvm.cuny.EDU (MITCHELL L GRAVES) writes:
>
> I have been using Turbo C for anly a few months now and I'm having a couple
>of problems with a program I'm writing.
>
...After using fgets() there is a printf:
>       printf("Password is: |%s|",&password);
>
>This is what it looks like when I print password:
>
>Password is: |ORANGE
>|
The reason is fgets(buf,n,stream) keeps the newline character if it reads one.
You can remove it easily by adding this line:
	fgets(buf,n,stream);		/* your specific fgets goes here */
	buf[strlen(buf)-1] = '\0';	/* ZAP that newline */

>
>Problem Two:
>
>I am drawing windows on the screen when  prompting for passwords & things
>of that nature.  I can watch the window being drawn (Very Sloooww!).  I heard
>there is a way to write the screen to a buffer (or something like that) and
>later call it up so I don't have to watch the window being slowly drawn each
>time.  Can anyone help me out?

(Under the assumption you're using and IBM PC or AT and you're using
text mode to do your painting.)
I've never done this in Turbo C, but used to do it in Turbo PASCAL all the 
time.  To write the screen the screen to a buffer just copy the screen
memory to your buffer and to put it back, just reverse the process.
Monochrome screen memory begins at 0xB000:0x0000 (segment:offset)
and color memory begins at 0xB800:0x0000 (segment:offset).  All you have
to do is set a pointer to the beginning of the right kind of memory 
(you can find out if you have a color or monochrome from a BIOS call,
but I don't know which offhand) and do a memcpy(buf,screen,4000) to
save the entire screen and memcpy(screen,buf,4000) to restore it.
If you need more help, just send me e-mail (address is ihnp4!richp1!kk).

-- 
Ken Konecki @ ihnp4!richp1!kk
"A squeegee by any other name wouldn't sound as funny"

Devin_E_Ben-Hur@cup.portal.com (02/13/88)

Turbo C 1.5 includes screen output functions that will write directly
to the screen map.  The upgrade is $33.50, free if you buy the Run time
library source.

flaps@dgp.toronto.edu (Alan J Rosenthal) (02/19/88)

In article <105@richp1.UUCP> kk@richp1.UUCP writes:
>	buf[strlen(buf)-1] = '\0';	/* ZAP that newline */

aaackk!  if strlen(buf) == 0 (it would be on EOF in your original
example) then this will trash some random other variable.  the safe
way to write this is:

	if(buf[0])
	    buf[strlen(buf) - 1] = '\0';

Actually, though, in your original example if fgets() failed the first
time then buf[] might simply have garbage in it, so taking its strlen()
is not safe.  Test the fgets() return value.

Furthermore, the original use of this code was to remove a trailing
newline.  If EOF occurs in the middle of a line, it is inelegant to
throw away the last character of the file.

So the final version is:

	if(fgets(...) && buf[0] && buf[strlen(buf) - 1] == '\n')
	    buf[strlen(buf) - 1] = '\0';

ajr
-- 
"noalias considered sailaon"

catone@dsl.cis.upenn.edu (Tony Catone) (02/27/88)

In article <105@richp1.UUCP> kk@richp1.UUCP (PUT YOUR NAME HERE) writes:
>
>Monochrome screen memory begins at 0xB000:0x0000 (segment:offset)
>and color memory begins at 0xB800:0x0000 (segment:offset).  All you have
>to do is set a pointer to the beginning of the right kind of memory 
>(you can find out if you have a color or monochrome from a BIOS call,
>but I don't know which offhand) and do a memcpy(buf,screen,4000) to
>save the entire screen and memcpy(screen,buf,4000) to restore it.

Be forewarned that the BIOS call to return the current display mode
(mono or color) is broken in the early BIOS versions of many PC
compatibles.  This once gave me quite a headache on my Leading Edge
Model M, until I tracked down what exactly was wrong.  The more 
reliable way to obtain the video mode is to read the value in the
BIOS low memory data table yourself.  The exact memory address is
commonly obtainable; send me mail if you can't find it and want it.

					- Tony
					  catone@dsl.cis.upenn.edu
					  catone@wharton.upenn.edu