|>
|> Does anyone out there have any bright ideas, routines, or references to
|> articles, good books etc. to help get INPUT for a C program quickly, easily
|> and painlessly?
|> It seems that every time I write something, I spend twice as long working
|> on the user interface as getting the main program done. I recently took
|> part in the Fourth Annual Duke Internet Programming Contest, and probably
|> the most difficult part of some of the programs was getting the input in in
|> the required format. Are there some well-known routines which will prompt for
|> and get values of various types (int, double, char, a string etc.) checking
|> that the values are in the correct format, in the correct range and allowing
|> for, say, a default or a quit option?
|>
|> Thanks,
|>
|> Nick
Below is at least a start; I would appreciate improvements...
----------------inter_template.h
extern void readUnsigned(char*, unsigned int *);
extern void readLongUnsigned(char*, long unsigned int *);
extern void readFloat(char*, float *);
extern void readDouble(char*, double *);
extern void readInt(char*, int *);
extern void readLongInt(char*, long int *);
extern void readChar(char*, char *);
extern void readShortInt(char*, short int *);
extern void readShortUnsigned(char*, unsigned short int *);
extern void readString(char*, char* *);
---------------inter_template.c
/*
* Provides robust interactive input for C's basic types.
* Users do not need to know about formats, or error recovery.
*
* Ian Cottam, Nov.93.
* Public Domain.
*/
# define SCANI(THE_FUNCNAME, THE_TYPE, THE_FORMAT) \
\
void THE_FUNCNAME(char *prompt, THE_TYPE *result) \
{ \
THE_TYPE value; \
char line[BUFSIZ]; \
int faulty; \
\
do { fputs(prompt==NULL?"":prompt, stderr); \
faulty= fgets(line, sizeof line, stdin) == NULL; \
if (faulty) \
clearerr(stdin); \
else \
faulty= sscanf(line , THE_FORMAT, &value) != 1; \
if (faulty) \
fputs( \
"\n[Fault - please re-enter a correct value]\n", \
stderr);\
} while (faulty); \
\
/* value is now well-defined */ \
*result= value; \
Quote:
}
# include <stdio.h>
# include <stddef.h>
# include "inter_template.h"
SCANI(readUnsigned, unsigned int, "%u")
SCANI(readLongUnsigned, unsigned long int, "%lu")
SCANI(readFloat, float, "%f")
SCANI(readDouble, double, "%lf")
SCANI(readInt, int, "%d")
SCANI(readLongInt, long int, "%ld")
SCANI(readShortInt, short int, "%hd")
SCANI(readShortUnsigned, unsigned short int, "%hu")
SCANI(readChar, char, "%c")
/* finally, and as always!, we need to special case strings */
/* Note. If you don't have a fgetline() - let me know */
# include "fgetline.h"
void readString(char *prompt, char **string)
{
int faulty; size_t len; char *line;
do { fputs(prompt==NULL?"":prompt, stderr);
line= fgetline(stdin, &len);
faulty= line == NULL;
if (faulty) {
clearerr(stdin);
fputs(
"\n[Fault - please re-enter a correct value]\n", stderr);
}
} while (faulty);
/* value is now well-defined */
if (line[len-1] == '\n')
line[len-1]= '\0';
*string= line;
Quote:
}
--
Ian Cottam, Room IT211, Department of Computer Science,
University of Manchester, Oxford Road, Manchester, M13 9PL, U.K.