Чтобы добиться максимальной производительности, вам необходимо различать доверенный и ненадежный ввод ваших функций.
Например, функция, подобная getBinNum()
, которая принимает ввод от пользователя, должна быть проверена на наличие допустимых символов и сжата для удаления начальных нулей. Сначала мы покажем функцию сжатия на месте общего назначения:
// General purpose compression removes leading zeroes.
void compBinNum (char *num) {
char *src, *dst;
// Find first non-'0' and move chars if there are leading '0' chars.
for (src = dst = num; *src == '0'; src++);
if (src != dst) {
while (*src != '\0')
*dst++ = *src++;
*dst = '\0';
}
// Make zero if we removed the last zero.
if (*num == '\0')
strcpy (num, "0");
}
Затем предоставьте функцию проверки, которая возвращает либо переданное значение, либо NULL, если оно недопустимо:
// Check untested number, return NULL if bad.
char *checkBinNum (char *num) {
char *ptr;
// Check for valid number.
for (ptr = num; *ptr == '0'; ptr++)
if ((*ptr != '1') && (*ptr != '0'))
return NULL;
return num;
}
Тогда сама функция ввода:
#define MAXBIN 256
// Get number from (untrusted) user, return NULL if bad.
char *getBinNum (char *prompt) {
char *num, *ptr;
// Allocate space for the number.
if ((num = malloc (MAXBIN)) == NULL)
return NULL;
// Get the number from the user.
printf ("%s: ", prompt);
if (fgets (num, MAXBIN, stdin) == NULL) {
free (num);
return NULL;
}
// Remove newline if there.
if (num[strlen (num) - 1] == '\n')
num[strlen (num) - 1] = '\0';
// Check for valid number then compress.
if (checkBinNum (num) == NULL) {
free (num);
return NULL;
}
compBinNum (num);
return num;
}
Другие функции для добавления или умножения должны быть написаны так, чтобы предполагать, что ввод уже действителен, поскольку он будет создан одной из функций в этой библиотеке. Я не буду предоставлять им код, поскольку он не имеет отношения к вопросу:
char *addBinNum (char *num1, char *num2) {...}
char *mulBinNum (char *num1, char *num2) {...}
Если пользователь выбирает источник своих данных откуда-то, кроме getBinNum()
, вы можете позволить ему вызвать checkBinNum()
для проверки.
Если бы вы были действительно параноиком, вы могли бы проверить каждый номер, переданный вашей подпрограмме, и действовать соответствующим образом (вернуть NULL), но для этого потребуются относительно дорогие проверки, которые не нужны.