atoi()
преобразует строковое представление целого числа в его значение. Он не будет преобразовывать произвольные символы в их десятичное значение. Например:
int main(void)
{
const char *string="12345";
printf("The value of %s is %d\n", string, atoi(string));
return 0;
}
В стандартной библиотеке C нет ничего, что могло бы преобразовать «A» в 65 или «Z» в 90, вам нужно написать это самостоятельно, особенно для любой кодировки, которую вы ожидаете ввести.
Теперь, когда вы знаете, что делает atoi()
, , пожалуйста, не используйте его , чтобы иметь дело с числовым вводом во всем, что вы придумали. Вы действительно должны иметь дело с вводом, а не с тем, что вы ожидаете. Хм, а что будет, когда я введу 65 вместо A? Учителя любят ломать вещи.
atoi()
не выполняет никакой проверки ошибок, что делает все, что полагается на него, для преобразования произвольного ввода хрупким, в лучшем случае. Вместо этого используйте strtol()
(пример, ориентированный на POSIX):
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(void)
{
static const char *input ="123abc";
char *garbage = NULL;
long value = 0;
errno = 0;
value = strtol(input, &garbage, 0);
switch (errno) {
case ERANGE:
printf("The data could not be represented.\n");
return 1;
// host-specific (GNU/Linux in my case)
case EINVAL:
printf("Unsupported base / radix.\n");
return 1;
}
printf("The value is %ld, leftover garbage in the string is %s\n",
// Again, host-specific, avoid trying to print NULL.
value, garbage == NULL ? "N/A" : garbage);
return 0;
}
При запуске это дает:
Значение 123, остаток мусора в
строка abc
Если вы не заботитесь о сохранении / проверке мусора, вы можете установить второй аргумент на NULL
. Там нет необходимости free(garbage)
. Также обратите внимание, что если вы передадите 0 в качестве третьего аргумента, предполагается, что входные данные - это желаемое значение десятичного, шестнадцатеричного или восьмеричного представления. Если вам нужно основание 10, используйте 10 - он потерпит неудачу, если вход не соответствует ожидаемому.
Вы также проверите возвращаемое значение для максимального и минимального значения, которое может обработать long int
. Однако, если оба возвращаются для указания ошибки, устанавливается errno
. Упражнение для читателя - изменить *input
с 123abc
на abc123
.
Важно проверить возврат, поскольку ваш пример показывает, что произойдет, если вы этого не сделаете. AbcDeFg не является строковым представлением целого числа, и вам нужно разобраться с этим в своей функции.
Для вашей реализации самый простой совет, который я могу вам дать, - это серия переключателей, например:
// signed, since a return value of 0 is acceptable (NULL), -1
// means failure
int ascii_to_ascii_val(const char *in)
{
switch(in) {
// 64 other cases before 'A'
case 'A':
return 65;
// keep going from here
default:
return -1; // failure
}
.. затем просто запустите это в цикле.
Или, предварительно заполни словарь, чтобы функция поиска могла охватывать (лучше). Вам не понадобятся хэши, только хранилище ключей -> значений, поскольку вы заранее знаете, что оно будет содержать, где стандартные символы ASCII - это ключи, а соответствующие им идентификаторы - значения.