Thread View: alt.msdos.programmer
1 messages
1 total messages
Started by Gregary John Boyles
Fri, 29 Dec 1995 14:55
Unpredictable C++ program behaviour!
Author: Gregary John Boyles
Date: Fri, 29 Dec 1995 14:55
Date: Fri, 29 Dec 1995 14:55
587 lines
17107 bytes
17107 bytes
Why does the Pascal version of this program behave exactly as expected while the
C++ version does not? Compiled with Borland C under DOS.
******************************* PASCAL VERSION *******************************
program show;
uses crt,dos,crt_,strings;
const maxstring=127;
escape=chr(27);
space=' ';
up='H';
down='P';
pageup='I';
pagedown='Q';
left='K';
right='M';
home='G';
end_='O';
null=chr(0);
type nodetypeptr=^nodetype;
nodetype=record
fileline:string;
filelinenum:integer;
next,previous:nodetypeptr;
end;
function empty(posptr:nodetypeptr):boolean;
begin
empty:=posptr=nil;
end;
procedure initialize(var listptr:nodetypeptr);
begin
listptr:=nil;
end;
procedure add(var listptr:nodetypeptr;fileline:string;filelinenum:integer);
var newptr,tempptr:nodetypeptr;
begin
new(newptr);
newptr^.fileline:=fileline;
newptr^.filelinenum:=filelinenum;
if (listptr=nil) then
begin
(listptr):=newptr;
(listptr)^.next:=nil;
(listptr)^.previous:=nil;
end
else
begin
tempptr:=listptr;
while (tempptr^.next<>nil) do
begin
tempptr:=tempptr^.next;
end;
tempptr^.next:=newptr;
newptr^.next:=nil;
newptr^.previous:=tempptr;
end;
end;
procedure remove(var listptr:nodetypeptr);
var tempptr:nodetypeptr;
begin
tempptr:=listptr;
listptr:=listptr^.next;
listptr^.previous:=nil;
dispose(tempptr);
end;
procedure setpos(var posptr:nodetypeptr;filelinenum:integer);
begin
while (posptr^.filelinenum<>filelinenum) do
begin
if (posptr^.filelinenum>filelinenum) then
begin
posptr:=posptr^.previous;
end
else if (posptr^.filelinenum<filelinenum) then
begin
posptr:=posptr^.next;
end;
end;
end;
procedure writescreenfull(width,height:word;posptr:nodetypeptr;stringpos:word);
var y,i:word;
line1:string;
begin
window(1,1,width,height);
clrscr;
window(1,1,width,height+1);
y:=1;
while (y<=height) and (not empty(posptr^.next)) do
begin
gotoxy(1,y);
i:=stringpos;
while (i<=length(posptr^.fileline)) and ((i-stringpos)<=width) do
begin
write(posptr^.fileline[i]+'');
i:=i+1;
end;
writeln;
posptr:=posptr^.next;
y:=y+1;
end;
end;
procedure main;
var infile:text;
x,width,height,back,fore:word;
ch:char;
numfilelines,filelinenum:integer;
listptr,posptr:nodetypeptr;
fileline,bottomfileline:string;
stringpos:word;
begin
if (paramcount<1) then
begin
writeln;
writeln('Show what . . .');
end
else
begin
{$I-}
assign(infile,paramstr(1));
{$I+}
if (doserror<>0) then
begin
writeln;
write('infile ');
write(paramstr(1));
writeln(' not found . . .');
end
else
begin
reset(infile);
initialize(listptr);
filelinenum:=0;
while (not eof(infile)) do
begin
readln(infile,fileline);
add(listptr,fileline,filelinenum);
filelinenum:=filelinenum+1;;
end;
numfilelines:=filelinenum-1;
close(infile);
posptr:=listptr;
fore:=textattr and $0f;
back:=(textattr and $70) div $10;
height:=hi(windmax);
width:=lo(windmax);
bottomfileline:=' '+chr(24)+' '+chr(25)+' pgup pgdn s "string" : (search for string) esc : (quit)';
for x:=length(bottomfileline)+1 to width do
begin
bottomfileline:=bottomfileline+' ';
end;
set_cursor(none);
clrscr;
textcolor(back);
textbackground(fore);
gotoxy(1,height);
write(bottomfileline);
textcolor(fore);
textbackground(back);
height:=height-1;
filelinenum:=1;
stringpos:=1;
writescreenfull(width,height,posptr,stringpos);
ch:=space;
while (ch<>escape) do
begin
while ((ch<>up) and (ch<>down) and (ch<>pageup) and
(ch<>pagedown) and (ch<>escape) and (ch<>left) and
(ch<>right) and (ch<>end_) and (ch<>home)) do
begin
ch:=readkey;
if (ch=null) then
begin
ch:=readkey;
end;
end;
if (ch=up) then
begin
if ((filelinenum-1)>=1) then
begin
filelinenum:=filelinenum-1;
end
else
begin
filelinenum:=1;
end;
setpos(posptr,filelinenum);
end
else if (ch=down) then
begin
if ((filelinenum+1+height)<=numfilelines) then
begin
filelinenum:=filelinenum+1
end
else
begin
filelinenum:=numfilelines-height+1;
end;
setpos(posptr,filelinenum);
end
else if (ch=pageup) then
begin
if ((filelinenum-height+1)>=1) then
begin
filelinenum:=filelinenum-height+1;
end
else
begin
filelinenum:=1;
end;
setpos(posptr,filelinenum);
end
else if (ch=pagedown) then
begin
if (((filelinenum+height-1)<=numfilelines) and
((numfilelines-(filelinenum+height-1))>=(height-1))) then
begin
filelinenum:=filelinenum+height-1;
end
else
begin
filelinenum:=numfilelines-height+1;
end;
setpos(posptr,filelinenum);
end
else if (ch=left) then
begin
if (stringpos>1) then
begin
stringpos:=stringpos-1;
end;
end
else if (ch=right) then
begin
if (stringpos<=(maxstring-width)) then
begin
stringpos:=stringpos+1;
end;
end
else if (ch=end_) then
begin
stringpos:=maxstring-width+1;
end
else if (ch=home) then
begin
stringpos:=1;
end;
if (ch<>escape) then
begin
ch:=space;
end;
writescreenfull(width,height,posptr,stringpos);
end;
height:=height+1;
window(1,1,width,height);
clrscr;
set_cursor(line);
while (not empty(listptr)) do
begin
remove(listptr);
end;
end;
end;
end;
begin
main;
end.
******************************** C++ VERSION *********************************
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <alloc.h>
#include <process.h>
const maxstring=127;
const lineend='\n';
const escape=27;
const null='\0';
const space=' ';
const up='H';
const down='P';
const pageup='I';
const pagedown='Q';
const left='K';
const right='M';
const home='G';
const end_='O';
typedef char string[maxstring];
typedef struct nodetypetag{string line;int linenum;struct nodetypetag *next,*previous;} nodetype;
typedef nodetype *nodetypeptr;
string line,line_,line1,bottomline;
char empty(nodetypeptr posptr)
{
return(posptr==NULL);
}
void initialize(nodetypeptr *listptr)
{
*listptr=NULL;
}
void add(nodetypeptr *listptr,char *fileline,int Linenum)
{
nodetypeptr newptr,tempptr;
newptr=(nodetypeptr)malloc(sizeof(nodetype));
strcpy(newptr->line,fileline);
newptr->linenum=Linenum;
if (*listptr==NULL)
{
(*listptr)=newptr;
(*listptr)->next=NULL;
(*listptr)->previous=NULL;
}
else
{
tempptr=*listptr;
while (tempptr->next!=NULL)
{
tempptr=tempptr->next;
}
tempptr->next=newptr;
newptr->next=NULL;
newptr->previous=tempptr;
}
}
void remove(nodetypeptr *listptr)
{
nodetypeptr tempptr;
tempptr=*listptr;
*listptr=(*listptr)->next;
(*listptr)->previous=NULL;
free(tempptr);
}
void setpos(nodetypeptr *posptr,int linenum)
{
while ((*posptr)->linenum!=linenum)
{
if ((*posptr)->linenum>linenum)
{
*posptr=(*posptr)->previous;
}
else if ((*posptr)->linenum<linenum)
{
*posptr=(*posptr)->next;
}
}
}
void writescreenfull(char width,char height,nodetypeptr posptr,char stringpos)
{
char y;
window(1,1,width,height);
clrscr();
window(1,1,width,height+1);
y=1;
while ((y<=height) && (!empty(posptr->next)))
{
gotoxy(1,y);
strcpy(line_,posptr->line);
line__=&(line_[stringpos]);
strncpy(line,line__,width-1);
strcat(line,null);
cputs(line);
posptr=posptr->next;
y++;
}
}
void removelineends(char *strings,unsigned int maxstrings)
{
unsigned int i;
i=0;
while ((i<maxstrings) && (strings[i]!=lineend))
{
i++;
}
strings[i]=null;
}
void main(int argc,char *argv[])
{
FILE *file;
char x,ch,width,height,back,fore,stringpos;
int numlines,linenum;
text_info info;
nodetypeptr listptr,posptr;
if (argc<2)
{
cputs("\nShow what . . .\n");
}
else
{
file=fopen(argv[1],"rt");
if (file==NULL)
{
cprintf("\nFile %s not found . . .\n",argv[1]);
}
else
{
rewind(file);
initialize(&listptr);
linenum=0;
while (fgets(line,maxstring,file)!=NULL)
{
removelineends(line,maxstring);
add(&listptr,line,linenum);
linenum++;
}
numlines=linenum--;
fclose(file);
posptr=listptr;
gettextinfo(&info);
fore=info.attribute&0x0f;
back=(info.attribute&0x70)/0x10;
height=info.screenheight;
width=info.screenwidth;
strcpy(bottomline," \30 \31 pgup pgdn s <string> (search for string) esc (quit)");
for(x=strlen(bottomline)+1;x<width;x++)
{
strcat(bottomline," ");
}
_setcursortype(_NOCURSOR);
clrscr();
textcolor(back);
textbackground(fore);
gotoxy(1,height);
cputs(bottomline);
textcolor(fore);
textbackground(back);
height--;
linenum=1;
stringpos=1;
writescreenfull(width,height,posptr,stringpos);
ch=space;
while (ch!=escape)
{
while ((ch!=up) && (ch!=down) && (ch!=pageup) &&
(ch!=pagedown) && (ch!=escape) && (ch!=left) &&
(ch!=right) && (ch!=end_) && (ch!=home))
{
ch=getch();
if (ch==null)
{
ch=getch();
}
}
if (ch==up)
{
if ((linenum-1)>=1)
{
linenum--;
}
else
{
linenum=1;
}
setpos(&posptr,linenum);
}
else if (ch==down)
{
if ((linenum+1+height)<=numlines)
{
linenum++;
}
else
{
linenum=numlines-height+1;
}
setpos(&posptr,linenum);
}
else if (ch==pageup)
{
if ((linenum-height+1)>=1)
{
linenum=linenum-height+1;
}
else
{
linenum=1;
}
setpos(&posptr,linenum);
}
else if (ch==pagedown)
{
if (((linenum+height-1)<=numlines) && ((numlines-(linenum+height-1))>=(height-1)))
{
linenum=linenum+height-1;
}
else
{
linenum=numlines-height+1;
}
setpos(&posptr,linenum);
}
else if (ch==left)
{
if (stringpos>1)
{
stringpos--;
}
}
else if (ch==right)
{
if (stringpos<=(maxstring-width))
{
stringpos++;
}
}
else if (ch==end_)
{
stringpos=maxstring-width+1;
}
else if (ch==home)
{
stringpos=1;
}
if (ch!=escape)
{
ch=space;
}
writescreenfull(width,height,posptr,stringpos);
}
height+=1;
window(1,1,width,height);
clrscr();
_setcursortype(_NORMALCURSOR);
while (!empty(listptr))
{
remove(&listptr);
}
}
}
}
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads