home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacFormat España 21
/
macformat_21.iso
/
Shareware
/
Programación
/
VideoToolbox
/
VideoToolboxSources
/
Choose.c
< prev
next >
Wrap
Text File
|
1995-10-24
|
6KB
|
184 lines
/*
Choose.c
Choose() uses the console to ask the user a multiple choice question and accept
a typed answer. It minimizes the number of keystrokes the user has to type. The
user can select the default answer by just hitting <cr>, or can select any of
the choices by typing just enough characters (typically just one) to make an
unambigious selection. Choose() automatically spells out the rest of the choice.
The user DOES NOT have to terminate the answer with a return. This makes it
feasible to ask the user a long series of multiple-choice questions, since the
user can quickly hit return to obtain default answers and need only type one (or
a few) characters to select non-default choices.
int Choose(int defaultChoice,const char *query,const char *choices[],int n);
choice=Choose(choice,"Will you eat %s?\n",breadFish,2);
The first argument and returned value are int, with values in the range 0 to
n-1, where n (the last argument) is the number of possible choices. The
second argument is a format string to be used (without the optional trailing
\n) in a printf statement. The optional %s will be expanded into a list of
alternatives appropriately punctuated by commas and "or". The third argument is
an array of n string pointers, one string per choice. If the second argument
ends in \n then the printing of that newline character is delayed until AFTER printing
the user's choice.
The other routines in this file, MultipleChoice() and YesOrNo() are obsolete,
since Choose() is more convenient, but they are retained for support of old
programs that may use them. Choose is implemented by calling MultipleChoice.
MultipleChoice() accepts (and echoes on the console) a partial typed response to
a multiple-choice question, expanding the response to print the full answer that
it uniquely specifies. If alternative answers begin with the same letters (e.g.
"Arabic" and "Armenian") then MultipleChoice keeps accepting characters until an
answer is uniquely determined. Typing any non-printing character (e.g. Return or
Enter) terminates the typed string, e.g. to distinguish "ant" from "anteater".
If the typed string doesn't match any of the supplied answer strings then
MultipleChoice makes the defaultChoice. Thus the user can select the default
answer by just hitting return.
YesOrNo() restricts the answers to "Yes" and "No", with a Boolean argument
specifying the default.
EXAMPLE:
static char bread[]="Bread",fish[]="Fish",fowl[]="Fowl";
static char *breadFishFowl[]={bread,fish,fowl};
short choice=1;
// new way
choice=Choose(choice,"Would you like to eat %s?\n",breadFishFowl,3);
stillHungry=Choose(stillHungry,"Do you want dessert?\n",noYes,2);
// old way
printf("Would you like to eat Bread, Fish, or Fowl?");
choice=MultipleChoice(choice,3,breadFishFowl);
printf("\n");
// old way
printf("Do you want dessert?");
choice=YesOrNo(choice);
printf("\n");
NOTE:
The declarations above explicitly allocate space for the strings "Bread" and "Fish".
In a stand-alone application you could implicitly allocate that space,
char *breadFishFowl[]={"Bread","Fish","Fowl"};
but the THINK C compiler doesn't allow this in code resources
(e.g. a MATLAB MEX file).
HISTORY:
2/16/93 dgp wrote YesOrNo().
5/24/93 dgp added MultipleChoice().
9/24/93 dgp cosmetic.
1/25/94 dgp enhanced MultipleChoice() to accept characters until they uniquely
specify an answer, as suggested by Bart Farell.
7/9/94 dgp added Choose().
7/13/94 dgp renamed file "Choose.c".
8/1/94 dgp fixed bug in MultipleChoice(), I was backspacing one too many times.
9/21/94 dgp added fflush(stdin) to MultipleChoice(), which works better when
there's no unbuffered input.
1/5/95 dgp updated to CW5, eliminating the cludges with SIOUXtextWindow.
6/18/95 dgp changed "abort" to "exit" for better compatibility with CW atexit().
*/
#include "VideoToolbox.h"
#if !defined(__TYPES__)
typedef unsigned char Boolean;
#endif
#define free(ptr) DisposePtr((Ptr)(ptr))
#define malloc(bytes) (void *)NewPtr(bytes)
static char no[]="No",yes[]="Yes";
char *noYes[]={no,yes};
int Choose(int defaultChoice,const char *query,char *choices[],int n)
{
Boolean newline;
int choice;
static char *string=NULL;
char *choiceList;
newline=(query[strlen(query)-1]=='\n');
choiceList=ChoiceStr(choices,n);
string=malloc(strlen(query)+strlen(choiceList)+1);
assert(string!=NULL);
//return defaultChoice=1;
sprintf(string,query,choiceList);
if(newline)string[strlen(string)-1]=0; // strip the trailing newline; print it later.
BreakLines(string,80);
printf("%s",string);
free(string);
choice=MultipleChoice(defaultChoice,n,choices);
if(newline)printf("\n");
return choice;
}
Boolean YesOrNo(Boolean defaultChoice)
/* Accept "y" or "n" and spell out "Yes" or "No". Anything else gets defaultChoice. */
{
return MultipleChoice(defaultChoice,2,noYes);
}
int MultipleChoice(short defaultChoice,short nChoices,char *choices[])
{
char c,s[64];
short i,j,choice,match,matches,k;
printf(" (%s):",choices[defaultChoice]);
fflush(stdout);
for(k=0;k<sizeof(s)-1;k++){
matches=0;
do{
c=getcharUnbuffered();
}while(c==EOF);
if(c==14)exit(1); /* Crude test for command-period. */
if(!isprint(c))c=0;
s[k]=c;
s[k+1]=0;
for(i=0;i<nChoices;i++){
match=1;
for(j=0;j<=k;j++)match&=(tolower(s[j])==tolower(choices[i][j]));
if(match){
choice=i;
matches++;
}
}
if(matches<=1 || s[k]==0)break;
printf("%c",c);
fflush(stdout);
}
fflush(stdin); // get rid of any unused input
/* Erase partial answer, which could be longer than the default answer. */
/* -1 because we didn't print the last character typed by the user. */
k=strlen(s)-1;
for(j=0;j<k;j++)printf("\b \b");
/* Print answer */
if(matches==0)choice=defaultChoice;
printf("%s.",choices[choice]);
fflush(stdout);
return choice;
}
char *ChoiceStr(char *choices[],int nChoices)
{
int i,size;
static char *string=NULL;
size=0;
for(i=0;i<nChoices;i++)size+=strlen(choices[i])+6;
string=realloc(string,size);
assert(string!=NULL);
string[0]=0;
for(i=0;i<nChoices;i++){
sprintf(string,"%s%s",string,choices[i]);
if(i<nChoices-2)sprintf(string,"%s, ",string);
if(i==nChoices-2){
if(nChoices>2)sprintf(string,"%s, or ",string);
else sprintf(string,"%s or ",string);
}
if(i==nChoices-1)sprintf(string,"%s",string);
}
return string;
}