这使用一个函数来获取一个范围内的整数,另一个函数来获取一系列整数。 strtol 用于解析使用fgets 获得的输入中的值。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
//inputs
// char *line : pointer to text to be parsed
// char **next : pointer to pointer to allow modification of caller's pointer
// char *term : pointer to characters to be considered terminators
// int *value : pointer to int to allow modification of caller's int
// int min : minimum value of range
// int max : maximum value of range
// returns : 0 failure or 1 success
int get_int_range ( char *line, char **next, char *term, int *value, int min, int max)
{
long int input = 0;
char *end = NULL;//will point to end of parsed value
errno = 0;
input = strtol ( line, &end, 10);//get the integer from the line. end will point to the end of the parsed value
if ( end == line) {// nothing was parsed. no digits
printf ( "input MUST be a number\n");
return 0;// return failure
}
// *end is the character that end points to
if ( *end != '\0' && ( strchr ( term, *end) == NULL)) {// is *end '\0' or is *end in the set of term characters
printf ( "problem with input: [%s] \n", line);
return 0;
}
if ( ( errno == ERANGE && ( input == LONG_MAX || input == LONG_MIN))
|| ( errno != 0 && input == 0)){// parsing error from strtol
perror ( "input");
return 0;
}
if ( input < min || input > max) {// parsed value is outside of range
printf ( "input out of range %d to %d\n", min, max);
return 0;
}
if ( next != NULL) {// if next is NULL, caller did not want pointer to end of parsed value
*next = end;// *next allows modification to caller's pointer
}
*value = input;// *value allows modification to callers int
return 1;// success
}
//inputs
// int cols : needed to pass in the variable length array
// int dest[][cols] : variable length array to be modified with parsed values
// int inputrow : row of the variable length array to be modified
// int min : mininum value of range
// int max : maximum value of range
// char *line : pointer to text to be parsed
// char *term : pointer to characters to be considered terminators
// returns : 0 failure or 1 success
int get_int_series ( int cols, int dest[][cols], int inputrow, int min, int max, char *line, char *term)
{
char *end = NULL;// will point to end of parsed value
char *each = NULL;// will point to start of parsed value
int valid = 0;
int input = 0;
int count = 0;
int temp[cols];// temporary storage for parsed values
each = line;// each points to start of line
do {
valid = get_int_range ( each, &end, term, &input, INT_MIN, INT_MAX);// call to parse one value
if ( !valid) {// failure
printf ( "input MUST be a number\n");
return 0;
}
if ( valid) {// success
temp[count] = input;// save parsed value in temporary array
count++;
if ( count > cols) {
printf ( "too many integers. %d entered. only enter %d\n", count, cols);
return 0;
}
}
// *end is the character that end points to
while ( *end && strchr ( term, *end)) {// if *end not '\0' and *end is in the set of term characters
end++;// yes. advance end one position
}
each = end;// set the end pointer to be the new starting pointer
} while ( end && *end);// keep looping the above while end is not NULL and *end is not '\0'
if ( count < cols) {
printf ( "too few integers. need %d entered. only entered %d\n", cols, count);
return 0;
}
while ( count) {
count--;
dest[inputrow][count] = temp[count];// set the values in the callers array to the values in the temporary array
}
return 1;// success
}
int main( int argc, char *argv[])
{
char line[900] = {'\0'};
int valid = 0;
int rows = 0;
int cols = 0;
int eachrow = 0;
int eachcol = 0;
do {
printf ( "Enter number of array rows or quit\n");
fgets ( line, sizeof ( line), stdin);//read a line
if ( strcmp ( line, "quit\n") == 0) {
return 1;// if quit is entered, exit the program
}
valid = get_int_range ( line, NULL, "\n", &rows, 0, INT_MAX);// call to parse a value
} while ( !valid);// on failure, keep looping the above
do {
printf ( "Enter number of array columns or quit\n");
fgets ( line, sizeof ( line), stdin);//read a line
if ( strcmp ( line, "quit\n") == 0) {
return 1;
}
valid = get_int_range ( line, NULL, "\n", &cols, 0, INT_MAX);
} while ( !valid);
//once the size is obtained, the variable length array can be declared
int array[rows][cols];
for(eachrow = 0; eachrow < rows; eachrow++) {// loop through the rows
do {
printf ( "Enter %d integers for row %d or quit. Ex 1 2 3\n", cols, eachrow + 1);
fgets ( line, sizeof ( line), stdin);//read a line
if ( strcmp ( line, "quit\n") == 0) {
return 1;
}
valid = get_int_series ( cols, array, eachrow, INT_MIN, INT_MAX, line, " \n");// call to obtain a series of values
} while ( !valid);// on failure, keep looping the above
}
// show the values in the variable length array
for(eachrow = 0; eachrow < rows; eachrow++) {
for(eachcol = 0; eachcol < cols; eachcol++) {
printf("[%d] ", array[eachrow][eachcol]);
}
printf("\n");
}
printf("\nDone\n");
return 0;
}