Search code examples
cuser-interfaceinputswitch-statementuser-input

What is the most efficient way to take in user input with many options in C?


I am writing a weather program that calls an API for data. One of the flags available is a preferred language, of which there are about 45 options. This leads me to the question.

What is the most efficient way to display all the language options, then allow user input, then check for valid input?

My best idea is a loop that prints all the options from a file. The user then inputs an option. Their selection is checked against the list to find a match. If there is a match then the program continues. If not, they are prompted again.

Is this the best way to go about this? I'm trying to make this program as efficient and professional looking as possible as I'm using it for my portfolio.


Solution

  • My best idea is a loop that prints all the options from a file. The user then inputs an option. Their selection is checked against the list to find a match. If there is a match then the program continues. If not, they are prompted again.

    Is this the best way to go about this? I'm trying to make this program as efficient and professional looking as possible as I'm using it for my portfolio.

    There are always multiple competing goals (single-thread performance, scalability, features, flexibility/extendibility, code readability, fault tolerance). For well designed code, its good to understand the importance of each of these goals for each piece of code (and good to understand that these importances can be different for different pieces of code in the same project). For this specific piece of code; I'd say that flexibility/extendibility (e.g. the ability to add new languages easily later) is the most important, followed by code readability (the ability to understand the code later, and find/fix bugs in it). The least important are scalability (e.g. how much performance increases when number of CPUs increases) then single-thread performance; because the code only needs to work once and is held back by the speed that a human can type anyway.

    Is this the best way to go about this? I'm trying to make this program as efficient and professional looking as possible as I'm using it for my portfolio.

    In terms of "human computer interaction"; the best way is to make it impossible for the user to enter invalid data (e.g. a drop down list with a well predicted default to avoid the need for a "not set yet" option). The second best way is "active status" - specifically, for every "user input event" (key press, mouse click, etc) a status field corresponding to the input field/control is updated to either indicate that the field/input is in an acceptable state, or provide the reason why it's not; where its impossible for the user to continue (e.g. because an "OK" button is disabled) until all of status fields are saying that the input is acceptable. For both of these options there is no need to validate the submitted input afterwards.

    Sadly; for "command line", it's almost impossible to use the best way and almost impossible to use the 2nd best way.

    In other words; you need to forget about performance/efficiency (because that's the least important); and then forget about writing software that is good/user-friendly (because it's command line).

    The question then is; what is the "least bad" option? For this; I'd start by assuming that the data for each language is stored in a separate file (or directory?) where the file name is usable for display purposes; and all of the data is in a specific directory (e.g. a "project/lang" directory that contains a "project/lang/UK_English" file, a "project/lang/Spanish" file, etc). In this case you can get a list of files in the "project/lang" directory, sort them in alphabetical order, and use them to display a list of numbered options ("1) Spanish", "2) UK English", ..). Then if/when the user selects an option you can validate it (and report any errors if the user entered a bad character, a number that's too high, etc, then ask the user to retry); and load the right file for whichever language they chose (and report any errors if there's a problem with the file and ask the user to choose something else).

    That way; people/translators can just create new files, and none of the code will need to be modified.

    For a comparison; the fastest way is to use constant strings (e.g. puts("1) Spanish\n2) UK English\n\nEnter language choice:")); and to predict what the user will choose (e.g. based on keeping track of what they chose last time) and "pre-fetch and pre-parse" in the background (so that hopefully all the work is done for the correct choice before the user actually makes a choice), with the ability to quickly cancel the "pre-fetch and pre-parse" work if the user makes a choice that wasn't predicted. This would be extremely good for performance (likely "instant") but extremely bad (inflexible, over-complicated, too hard to maintain).