Почему я получаю этот неожиданный результат, используя atoi () в C?

Я не понимаю результаты следующего C-кода.

main() { char s[] = "AAA"; advanceString(s); } void advanceString(p[3]) { int val = atoi(p); printf("The atoi val is %d\n",val); } 

Здесь значение atoi показано как 0, но я не мог точно определить причину. По моему пониманию, это должно быть суммирование десятичных эквивалентов каждого значения в массиве? Пожалуйста, поправьте меня, если я ошибаюсь.

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  #include  #include  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 до 123abc .

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

Он пытается преобразовать строку в целое число. Поскольку AAA не может быть преобразован в целое число, значение равно 0. Попробуйте дать ему 42 или что-то еще.

Если действительное преобразование не было выполнено, возвращается нулевое значение.

См. http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

Прочитайте atoi() как a to i (ASCII – целое число).

atoi() преобразует строку, представляющую десятичное число, в целое число.

 char s[] = "42"; int num = atoi(s); //The value of num is 42. 

atoi ожидает, что его аргумент будет строковым представлением десятичной (base-10) целочисленной константы; AAA не является допустимой десятичной целочисленной константой, поэтому atoi возвращает 0, потому что у него нет другого способа указать, что вход недействителен.

Обратите внимание, что atoi преобразуется до первого символа, который не является частью действительной целочисленной константы; другими словами, «123» и «123w» оба будут преобразованы в 123.

Как все говорят, не используйте atoi ; strtol этого используйте strtol .

  • Асинхронный процесс начнется и дождитесь его завершения
  • byte в hex string
  • Как получить доступные точки доступа Wi-Fi и их уровень сигнала в .net?
  • В чем разница между созданием экземпляра объекта с использованием нового vs.
  • Установщик WiX msi не устанавливает приложение Winform, созданное с помощью Visual Studio 2017
  • C # - выборочное подавление пользовательских устаревших предупреждений
  • Поставщик Microsoft.Jet.OLEDB.4.0 не зарегистрирован на локальной машине
  • Как читать данные из zip-файла без необходимости разархивировать весь файл
  • Явная специализация в области пространства имен (дубликат)
  • dynamic_cast и static_cast в C ++
  • В C #, что происходит, когда вы вызываете метод расширения на нулевом объекте?
  • Давайте будем гением компьютера.