Перейти к содержанию
    

Про atoi сказанно так

Quote

Return Value

This function returns the converted integral number as an int value. If no valid conversion could be performed, it returns zero.

то есть я не буду знать это мусорный аргумент или я передал строку "0". но вот IAR например в отладке помечает NaN (Not a Number). но в коде он это не видит

num = atoi("a0b1");
if (num == NaN)

ругается - NaN - undefined. это значит не судьба попользоваться NaNом в коде?

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

NaN - это IEEE 754, он только про плавающую точку. А atoi - про целые числа. В целые числа NaN никак впихнуть нельзя.

Помимо этого, сравнение на равенство NaN некорректно, так как по IEEE 754 (если я ничего не путаю) NaN не равен ничему - в том числе и самому себе (то есть (NaN == NaN) равно false). Для проверки на NaN нужно использовать функцию isNaN (или как-то так, точно имя не помню).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 11/23/2022 at 1:47 PM, engel65536 said:

NaN - это IEEE 754, он только про плавающую точку. А atoi - про целые числа. В целые числа NaN никак впихнуть нельзя.

Помимо этого, сравнение на равенство NaN некорректно, так как по IEEE 754 (если я ничего не путаю) NaN не равен ничему - в том числе и самому себе (то есть (NaN == NaN) равно false). Для проверки на NaN нужно использовать функцию isNaN (или как-то так, точно имя не помню).

понял. спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 минут назад, jenya7 сказал:

то есть я не буду знать это мусорный аргумент или я передал строку "0".

Пользуйте strtol() или strtoul() вместо atoi(). И будет счастье.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 11/23/2022 at 2:01 PM, jcxz said:

Пользуйте strtol() или strtoul() вместо atoi(). И будет счастье.

а что так можно было?

 

проверил

long lv = strtol("a0b1", NULL, 10);

вернулся 0. 

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Используйте endptr (второй аргумент) для того, чтобы понять, успешно распарсилось или нет

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 11/23/2022 at 2:20 PM, engel65536 said:

Используйте endptr (второй аргумент) для того, чтобы понять, успешно распарсилось или нет

а условие успеха будет (endptr != NULL) ?

 

ну вот скажем

 long lv = strtol("123a0b1", &ptr, 10);

lv = 123

ptr = ""a0b1"

 

но можно ли принять такую строку как валидный аргумент? (ну да. это уж мне решать).

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 минут назад, jenya7 сказал:

а условие успеха будет (endptr != NULL) ?

*endptr == '\0', т.е. он указывает на конец строки, вся строка была преобразована полностью. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 11/23/2022 at 2:36 PM, Сергей Борщ said:

*endptr == '\0', т.е. он указывает на конец строки, вся строка была преобразована полностью. 

так он всегда указывает на конец строки даже когда строка пустая.

 

нет. я ошибся.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, jenya7 сказал:

так он всегда указывает на конец строки даже когда строка пустая.

Вы противоречите самому себе:

21 минуту назад, jenya7 сказал:

ну вот скажем

 long lv = strtol("123a0b1", &ptr, 10);

lv = 123

ptr = ""a0b1"

А проверить исходную строку на пустоту можно перед вызовом. Или как-то еще обеспечить, чтобы пустая строка на вход этой функции не попадала. Или пишите свою функцию преобразования строки в число - там сможете все свои хотелки реализовать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 11/23/2022 at 2:47 PM, Сергей Борщ said:

Вы противоречите самому себе:

А проверить исходную строку на пустоту можно перед вызовом. Или как-то еще обеспечить, чтобы пустая строка на вход этой функции не попадала. Или пишите свою функцию преобразования строки в число - там сможете все свои хотелки реализовать.

не так понятно дело можно проверять строку и так и этак. но хочется ж без лишних наворотов. 🙂

 

в IAR я склоняюсь к использованию strtol. у них все ф-ции из stdlib очень шустрые. как в других компайлерах не знаю, может стоит и свою написать.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

49 минут назад, jenya7 сказал:

так он всегда указывает на конец строки даже когда строка пустая.

Он указывает всегда на символ, вызвавший останов разбора строки. Прочтите наконец-то описание функций!

Если ни одного символа корректного не было - будет содержать начальный указатель (первый аргумент).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 вот еще такой вопрос. где алоцируется строковая часть "abc"? я ведь определяю только указатель.

char *ptr;

long lv = strtol("123abc", &ptr, 10);

lv = 123

ptr = "abc"

а физически где строка находиться? понятно в RAM но по какому принципу ф-ция выделяет место?

 

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если после вызова (*endptr != str) && (*endptr указывает на допустимый символ границы числа) -> значит разбор был корректный.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, jcxz said:

Если ни одного символа корректного не было - будет содержать начальный указатель (первый аргумент).

if ((endptr == input_str) || (*endptr != '\0')) printf("Bad input");

Как-то так.

1 minute ago, jenya7 said:

а физически где строка находиться? понятно в RAM но по какому принципу ф-ция выделяет место?

Указатель указывает на вашу же строку (только в общем случае не на первый символ), которую вы передали в качестве параметра в strtol.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...