I am attempting to convert the following C++ program to EBasic:
/*
Name: EXERCISE 3-04
Book: Teach Yourself C++
Copyright: 1990 by Management Information Source, Inc.
Author: Al Stevens
Date: 04/07/07 00:22
Description: The C++ free store: more dynamic array allocation
*/
#include <cstdlib>
#include <iostream>
using namespace std;
int comp(const void *a, const void *b)
{
return strcmp(*(char **)a, *(char **)b);
}
int main(int argc, char *argv[])
{
cout << "How many names at most? ";
int maxnames;
cin >> maxnames;
char **names = new char *[maxnames];
int namect;
for (namect = 0; namect < maxnames; namect++) {
cout << "Enter a name: ";
char *name = new char[80];
cin >> name;
if (strcmp(name, "end") == 0)
break;
names[namect] = new char[strlen(name)+1];
strcpy(names[namect], name);
delete name;
}
qsort(names, namect, sizeof(char *), comp);
for (int i = 0; i < namect; i++)
cout << names[i] << '\n';
for (int i = 0; i < namect; i++)
delete names[i];
delete names;
cout << "\n\n";
system ("pause"); /* execute M$-DOS' pause command */
return EXIT_SUCCESS;
}
' Ex-03-04.eba
' The free store: more dynamic array allocation.
'
$MAIN
AUTODEFINE "off"
$INCLUDE "waitkey$.inc"
DECLARE IMPORT, GetTickCount(),UINT
OPENCONSOLE
DEF time1 AS UINT
DEF time2 AS UINT
time1 = GetTickCount()
int maxnames,namect,i
pointer pname,ppnames
istring name[80]
INPUT "How many names at most? ",maxnames
ppnames=new(pointer,maxnames)
FOR namect=0 TO maxnames-1 STEP 1
INPUT "Enter a name: ",name
IF name="end" THEN BREAKFOR
ppnames[namect]=new(char,LEN(name)+1)
ppnames[namect]=name
' delete pname
NEXT namect
FOR i=0 TO namect-1
PRINT *<string>ppnames[i]
NEXT i
'region
SETPRECISION (3)
time2 = GetTickCount()
PRINT:PRINT (time2-time1), "ms."
PRINT:PRINT "Done..."
PRINT:PRINT "Press any key to end program."
PRINT
WaitKey$()
CLOSECONSOLE
END
'endregion
. . . and I'm getting nowhere.
This should get you a little closer but not exactly there.
$MAIN
AUTODEFINE "off"
DECLARE IMPORT, GetTickCount(),UINT
OPENCONSOLE
DEF time1 AS UINT
DEF time2 AS UINT
time1 = GetTickCount()
int maxnames,namect,i
pointer pname,ppnames[100]
istring name[80]
INPUT "How many names at most? ",maxnames
ppnames=new(pointer,maxnames)
FOR namect=0 TO maxnames-1 STEP 1
INPUT "Enter a name: ",name
IF name="end" THEN BREAKFOR
ppnames[namect]=new(string,1)
#<string>ppnames[namect]=name
' delete pname
NEXT namect
FOR i=0 TO namect-1
PRINT #<string>ppnames[i]
NEXT i
'region
SETPRECISION (3)
time2 = GetTickCount()
PRINT:PRINT (time2-time1), "ms."
PRINT:PRINT "Done..."
PRINT:PRINT "Press any key to end program."
PRINT
do:until inkey$<>""
CLOSECONSOLE
END
Larry
Thanks, Larry.
That was most helpful.
The POINTER as type for NEW is still not working, I've used an INT instead. Added also two optimizations:
- "name = new" moved outside the loop
- "delete names" moved to previous loop with cout.
The comparing function for qsort must be cdecl:
$include "stdio.inc"
$include "string.inc"
declare cdecl comp(pointer a, pointer b),int
sub comp(pointer a, pointer b),int
return strcmp(*<pointer>a, *<pointer>b)
endsub
'int main(int argc, char *argv[])
int maxnames
int namect
pointer name
pointer names
int i
input "How many names at most? ", maxnames
names = new(int, maxnames)
name = new(char, 80) /*moved outside for{}, why allocate/delete multiple times?*/
for namect = 0 to maxnames-1
input "Enter a name: ", *<string>name
if (strcmp(name, "end") = 0) then _
breakfor
*<pointer>names[namect] = new(char, strlen(name)+1)
strcpy(*<pointer>names[namect], name)
next namect
delete name
qsort(names, namect, len(pointer), &comp)
for i = 0 to namect-1
puts(*<pointer>names[i])
delete *<pointer>names[i] /*moved here from next for{}*/
next i
delete names
puts("\n")
_system ("pause")
Thank you, Sapero.
Very illuminating, as usual.
:)