What would be the easiest way to consider user input. Sometimes the action that I would like to take requires an input of "print" from the user, but other times I need something like "add input1 input2".
If I do something like:
success = fscanf(stdin,"%s %s %s", cmd, input1, input2)
the program will continue on until there are three things inputted every time. The menu for the program is built around comparing strings to the value main_input, but often times the optional inputs are not needed.
Example of what I am talking about:
int echo = 0; // controls echoing, 0: echo off, 1: echo on
if(argc > 1 && strcmp("-echo",argv[1])==0) { // turn echoing on via -echo command line option
echo=1;
}
printf("TreeMap Editor\n");
printf("Commands:\n");
printf(" quit: exit the program\n");
printf(" print: shows contents of the tree in reverse sorted order\n");
printf(" add <key> <val>: inserts the given key/val into the tree, duplicate keys are ignored\n");
printf(" get <key>: prints FOUND if the name is in the tree, NOT FOUND otherwise\n");
printf(" clear: eliminates all key/vals from the tree\n");
printf(" size: prints the total number of nodes in the tree\n");
printf(" preorder: prints contents of the tree in pre-order which is how it will be saved\n");
printf(" save <file>: writes the contents of the tree in pre-order to the given file\n");
printf(" load <file>: clears the current tree and loads the one in the given file\n");
char cmd[128];
char input1[128];
char input2[128];
treemap_t treemap;
int success;
treemap_init(&treemap);
while(1){
printf("TM> "); // print prompt
success = fscanf(stdin,"%s %s %s",cmd, input1, input2); // read a command
if(success==EOF){ // check for end of input
printf("\n"); // found end of input
break; // break from loop
}
if( strcmp("quit", cmd)==0 ){ // check for exit command
if(echo){
printf("quit\n");
}
printf("quit\n");
break; // break from loop
}
else if( strcmp("print", cmd)==0 ){ // insertion
if(echo){
printf("what!!! %s\n",cmd);
}
printf("hellur?\n");
}
else if( strcmp("add", cmd)==0 ){ // get command
if(echo){
printf("im in add");
}
printf("Your variables are: %s %s\n", input1, input2);
}
else{ // unknown command
if(echo){
printf("%s\n",cmd);
}
printf("unknown command %s\n",cmd);
}
}
return 0;
}
if you run this program and input "Quit" for example, it should just exit out of the program right then and there. However, it will wait for 2 other inputs before it compares the inputted string to cmd.
From what I have read I may need to do something with fgets()?? I am a novice programmer and I cannot make sense of this at the moment.
CodePudding user response:
Here's a crude sketch of dealing with user input that may involve different numbers of parameters of different types. Perhaps this will get you started.
int main() {
char buf[ 128 ]; // sufficient?
for(;;) {
printf(
"\n"
"crawl: blah\n"
"walk: blah\n"
"jog speed: blah\n"
"drive min max: blah\n"
"rip: blah\n"
">> "
);
fgets( buf, sizeof buf, stdin ); // user input
char *p = strtok( buf, " \n" ); // first "word" isolated
if( stricmp( p, "crawl" ) == 0 ) // case insensitive
printf( "So cute!\n" );
else if( stricmp( p, "walk" ) == 0 )
printf( "Take out the garbage.\n" );
else if( stricmp( p, "jog" ) == 0 ) {
p = strtok( NULL, " \n" );
printf( "You think you can sustain %dkph?\n", atoi(p) );
}
else if( stricmp( p, "drive" ) == 0 ) {
int min = atoi( strtok( NULL, " \n" ) );
int max = atoi( strtok( NULL, " \n" ) );
printf( "Between %d and %d\n", min, max );
}
else if( stricmp( p, "rip" ) == 0 ) {
printf( "Well remembered...\n" );
break;
}
else
printf( "Stick to the menu\n" );
}
return 0;
}
This is a quick demonstration. A superior technique would assemble an array of 'prompt' words to be used, their explanation ("blah"), and a function pointer to a 'handler' function. This is left as an exercise for the reader.
CodePudding user response:
Here's a simple example using fgets
and sscanf
to check the number of arguments:
#include <stdio.h>
#include <string.h>
int
main(void)
{
struct cmd {
const char *cmd;
int arg_count;
const char *help;
const char *aux;
} cmds[] = {
{ "quit", 0, "exit the program" },
{ "print", 0, "show contents of the tree in reverse sorted order" },
{ "add", 2, "insert the given key/val into the tree, "
"duplicate keys are ignored", " <key> <val>" },
{ "get", 1, "print FOUND if the name is in the tree, "
"NOT FOUND otherwise", " <key>" },
{ "clear", 0, "eliminate all key/vals from the tree" },
{ "size", 0, "print the total number of nodes in the tree" },
{ "preorder", 0, "print contents of the tree in pre-order which "
"is how it will be saved" },
{ "save", 1, "write the contents of the tree in pre-order to "
"the given file", " <file>" },
{ "load", 1, "clear the current tree and loads the one in "
"the given file", " <file>" },
};
struct cmd *end = cmds sizeof cmds / sizeof *cmds;
for( struct cmd *c = cmds; c < end; c ){
char hdr[128];
sprintf(hdr, "%s%s:", c->cmd, c->aux ? c->aux : "");
printf(" %-17s%s\n", hdr, c->help);
}
char buf[128];
char cmd[128];
char input1[128];
char input2[128];
while( NULL != fgets(buf, sizeof buf, stdin) ){
int count = sscanf(buf, "7s 7s 7s", cmd, input1, input2);
struct cmd *c;
for( c = cmds; c < end; c ){
if( strcmp(cmd, c->cmd) == 0 ){
if( count - 1 != c->arg_count ){
fprintf(stderr, "Invalid cmd: %s",
buf);
} else {
printf("valid cmd: %s", buf);
}
break;
}
}
if( c == end ){
fprintf(stderr, "command not found: %s\n", cmd);
}
}
}