Ответ 1
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 вместо А? Учителя любят нарушать вещи.
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 - он будет терпеть неудачу, если вход не такой, как вы ожидаете.
Вы также проверите возвращаемое значение для максимального и минимального значения, которое может обрабатывать a 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 являются ключами, а их соответствующие идентификаторы - значениями.