Полагаю, мне нужно использовать комбинацию scanf () и strtok ()
Я бы предположил иначе:
пользователь может ввести «почти бесконечное» количество нулей перед любым числом, или много пробелов, или много нулей после десятичной точки, или .... Это означает, что вы не можете ожидать ( например) иметь все цифры числа в оперативной памяти одновременно; это означает, что ни одна из функций, предоставляемых C, не может быть использована.
ошибки случаются. При разборе текста однозначная и описательная обратная связь должна считаться обязательной, независимо от того, был ли текст получен от пользователя (который должен знать, почему его текст не понравился) или из файла или другого компьютера (где разработчик должен иметь возможность найти / исправить проблемы).
Лучше всего было избежать обеих проблем с помощью конечного автомата в цикле; как может быть:
int state = NEWLINE;
unsigned int lineNumber = 0;
unsigned int dataNumber;
while( ((c = getChar()) != EOF)) && (state != ERROR) ) {
switch(state) {
case NEWLINE:
lineNumber++;
if(isDigit(c) {
number = c - '0';
state = FIRST_NUMBER_STARTED;
dataNumber = 1;
} else {
printf("ERROR: Character at start of line is not a valid decimal digit\n");
state = ERROR;
}
break;
case FIRST_NUMBER_STARTED:
if(isDigit(c) {
digit = c - '0';
if(number > UINT_MAX/10) {
printf("ERROR: First number on line %u is too large\n", lineNumber);
state = ERROR;
} else {
number *= 10;
if(number > UINT_MAX - digit) {
printf("ERROR: First number on line %u is too large\n", lineNumber);
state = ERROR;
} else {
number += digit;
}
}
} else if(c == ';') {
state = COLON_FOUND;
} else {
printf("ERROR: Invalid character after first number on line\n");
state = ERROR;
}
break;
case COLON_FOUND:
if(isDigit(c) {
number = c - '0';
state = DATA_NUMBER_STARTED;
} else {
printf("ERROR: Character at start of data not a valid decimal digit\n");
state = ERROR;
}
break;
case DATA_NUMBER_STARTED:
if(isDigit(c) {
digit = c - '0';
if(number > UINT_MAX/10) {
printf("ERROR: Data number %u on line %u is too large\n", dataNumber, lineNumber);
state = ERROR;
} else {
number *= 10;
if(number > UINT_MAX - digit) {
printf("ERROR: Data number %u on line %u is too large\n", dataNumber, lineNumber);
state = ERROR;
} else {
number += digit;
}
}
} else if(c == ',') {
state = COMMA_FOUND;
} else if(c == '\n') {
state = NEW_LINE;
} else {
printf("ERROR: Invalid character after data number %u on line %u\n", dataNumber, lineNumber);
state = ERROR;
}
break;
case COMMA_FOUND:
dataNumber++;
if(isDigit(c) {
number = c - '0';
state = FIRST_NUMBER_STARTED;
} else if(c == '\n') {
printf("ERROR: Missing number after comma at end of line %u\n", lineNumber);
state = ERROR;
} else {
printf("ERROR: Invalid character after comma (after data number %u) on line %u\n", dataNumber-1, lineNumber);
}
break;
}
}
Примечание. Пример кода не хранит никаких данных и вообще не обрабатывает пробелы (или десятичные точки, или ...) (для этого можно добавить больше кода и новые состояния) и т. Д. В основном; это «очень непроверенный» код, предназначенный только для примера.