forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   C++ (http://forum.boolean.name/forumdisplay.php?f=22)
-   -   Проверка: является ли строка числом? (http://forum.boolean.name/showthread.php?t=9230)

impersonalis 24.09.2009 11:55

Проверка: является ли строка числом?
 
Требуется сабжевая фунЕция:
необходимо проверить - можно ли содержащийся в переданном указателе на начало нуль-терминированной строки текст интерпретировать как число, в соответствии со всякими там RFC. Не хочу изобретать велик. Но если грамотных реализаций нет - то могу и обойтись)

РЕШЕНИЕ СМОТРИ В КОНЦЕ ТЕМЫ

Knightmare 24.09.2009 12:10

Ответ: Проверка: является ли строка числом?
 
Эм, спроси у MSDN про isdigit. Там правда для отдельного символа, но допилить для прверки строки уже дело техники.

impersonalis 24.09.2009 12:23

Ответ: Проверка: является ли строка числом?
 
Цитата:

Определяет, является ли самый левый символ заданного символьного выражения цифрой (от 0 до 9).
Это шняга какая-то =(
Мне надо, чтобы он корректно реагировал на числа типа:
-12.7е-984

Knightmare 24.09.2009 12:38

Ответ: Проверка: является ли строка числом?
 
Ну фиг знает, это не пойдет http://www.boost.org/doc/libs/1_40_0...xical_cast.htm? Вообще можно в бусте покопаться, там много всякой фигни.

ABTOMAT 24.09.2009 12:42

Ответ: Проверка: является ли строка числом?
 
Ну, я думаю, всё же пригодится :)
Основа-то - проверка символов:
- на +/-
- на цифры
- на Е или е
Ну и допилить порядок проверки

impersonalis 24.09.2009 13:15

Ответ: Проверка: является ли строка числом?
 
Цитата:

- на +/-
- на цифры
- на Е или е
-на места вхождения знака
-на кол-во вхождений знаков
-на плавающую точку
-на место ПТ
-на количество вхождений ПТ
-на корректность диапазона показателя
-на корректность диапазона мантиссы
+куча стаффа оговорённого стандартами текстового представления дробных чисел.
Ну и финал:
Цитата:

Не хочу изобретать велик. Но если грамотных реализаций нет - то могу и обойтись)
Т.к. реализовал уже разборку подобных вещей, когда писал класс для работы с большими числами (но там я был законодателем стандартов, превосходящих привычные числа)

Knightmare 24.09.2009 13:19

Ответ: Проверка: является ли строка числом?
 
Ну тебе скорее писать велосипед придется, если задача не типичная (не тупо взять строку с числом и перегнать в int или float).

Dream 24.09.2009 14:21

Ответ: Проверка: является ли строка числом?
 
atoi, strtol, strtod .etc не подходит? ну или другие СТЛ функции для перевода в числа строк, вроде есть там для перевода с плавающей точкой

impersonalis 24.09.2009 14:43

Ответ: Проверка: является ли строка числом?
 
Мне не перевести надо, а чекнуть валидность.
Можно конечно проверить результат конверта, и если он =0, а число не ноль, то фолс.

Knightmare 24.09.2009 14:47

Ответ: Проверка: является ли строка числом?
 
Не получится. Они конвертят до тех пор пока не встретит левый символ (типично если строка - валидное число это нулевой байт означающий конец строки).

SBJoker 24.09.2009 15:01

Ответ: Проверка: является ли строка числом?
 
А что конвертнуть строку в число, а потом проверить получилось ли число в результате, если получилось то строка может быть преобразована в число! По моему логично. А вообще это какой то маразм неиметь подобных функций "из коробки". Все современные языки располагают такими типичнейшими возможностями без добавок сторонних длл или модулей.

Ктоме того парсить числа нужно на основе текущей локали пользователя, ибо форматирование чисел может значительно отличаться от локали к локали. Начиная от разделителя дробной части и заканчивая правилами форматирования отрицательных чисел и дробных чисел.

З.Ы. в VB 6.0 - isNumeric("ололо")
в С# - float.TryParse("15445.1")

impersonalis 24.09.2009 15:27

Ответ: Проверка: является ли строка числом?
 
Цитата:

проверить получилось ли число в результате
вот как это сделать?
"12БЛДЖАД!" - превратитцо в "12"
которое число

SBJoker 24.09.2009 17:38

Ответ: Проверка: является ли строка числом?
 
Ну если важно определить до единого ли символа строка число, то имеет смысл обратная конверсия и сравнение либо длин либо побайтово.

Phantom 24.09.2009 20:45

Ответ: Проверка: является ли строка числом?
 
В PHP есть функция is_numeric(), которая проверяет, является ли строка числом. Точнее находится ли в строке число. Короче, вот пример:
Цитата:

<?php

$str='123.345E-12';

if(is_numeric($str)) echo 'OK';

?>
Выведет OK. Осталось выдрать функцию из исходников PHP =)

IGR 24.09.2009 21:07

Ответ: Проверка: является ли строка числом?
 
угу в АкшнСкрипт тоже !! :)

SBJoker 24.09.2009 21:13

Ответ: Проверка: является ли строка числом?
 
Только в великом и могучем С++ нету...

zombiee 24.09.2009 21:44

Ответ: Проверка: является ли строка числом?
 
PHP код:

bool isdigit(char *Num){
  
double Res=atof(Num);
  if(
Res!=0){
    return 
true;
  }else if(
stricmp(Num"0")==0){
      return 
true;
  }

  return 
false;


Родил... Вроде как работает) Но, блин:
23.2gh465E-1 - число
23.2465E-1 - число
sdgf23.2465E-1 - не число
т.е если первый символ - число, то и вся строка числом считается. Иначе - нет. Вотъ.
:wallbash: Только если в ручную парсить строку, тогда и будет понятно. со sscanf - то же самое.... Щас ещё подумаю.
// Сорри, блин, щас тока тему прочитал... Это уже обсуждалось)))))
// Да, и ещё - из пыха выдрать трудно будет. Там 5-6 (особо не вникал) функций по 200-300 строк кода... И каждую переписывать О_о

// В чистом виде нету... Есть в boost::lexical_cast. Го в гугл)
// Спасибо OreZ за подсказку)

Knightmare 24.09.2009 21:47

Ответ: Проверка: является ли строка числом?
 
Сказано же было - все эти функции работают пока не встретят левый символ, поэтмоу в первом случае на выходе "23.2", что есть число как бэ. В данном конкретном случае - ручной парсинг всей строки и проверка каждого символа. Если все символы до '\0' прошли проверку - это число.

zombiee 24.09.2009 22:12

Ответ: Проверка: является ли строка числом?
 
Да-да, меня Фантом попросил функцию из пыха выдрать) Но когда я увидел, что придётся делать - что-то мне перехотелось) Вот, нашёл в сети - функция разбора действительных чисел на чистом C++ попробуй...

impersonalis 25.09.2009 01:16

Ответ: Проверка: является ли строка числом?
 
Чот жесть, мне кажется - у меня компактнее это происходило.
Всем спасибо, подождём ещё)

zombiee 25.09.2009 01:34

Ответ: Проверка: является ли строка числом?
 
Импер, что ты собираешься ждать?) Тебе же дали готовый пример) Переписывай под себя и всё.

impersonalis 10.10.2009 03:29

Ответ: Проверка: является ли строка числом?
 
Уж дедлайн близится, а реализации всё нет.
Взял и набросал следующее:
Код:

bool Check(char *s,int LEN){
        enum SymbolIs{DIGIT,EXP,SEP,SIGN,ETC};
        SymbolIs Key;
        int i;
        int Epos=-1;
        int Spos=-1;
        bool ExitFlg=true;
        for(i=0;i<LEN && ExitFlg;i++){
                if(s[i]>='0' && s[i]<='9'){
                        Key=DIGIT;
                }
                else if(s[i]=='E' || s[i]=='e'){
                        Key=EXP;
                }
                else if(s[i]=='.' || s[i]==','){
                        Key=SEP;
                }
                else if(s[i]=='+' || s[i]=='-'){
                        Key=SIGN;
                }
                else{
                        Key=ETC;
                }
                switch(Key){
                        case DIGIT:{
                                break;
                                          }
                        case EXP:{
                                if(Epos!=-1){
                                        ExitFlg=false;
                                        break;
                                }
                                Epos=i;
                                break;
                                        }
                        case SEP:{
                                if(Spos!=-1){
                                        ExitFlg=false;
                                        break;
                                }
                                Spos=i;
                                break;
                                        }
                        case SIGN:{
                                if(i==0 || Epos==i-1){
                                        break;
                                }
                                ExitFlg=false;
                                break;
                                          }
                        case ETC:{
                                ExitFlg=false;
                                break;
                                        }
                }
        }
        return ExitFlg;
}

Прогоним на тестах:

Тест SBJoker
Цитата:

"ололо"
0
"15445.1"
1

Тест impersonalis
Цитата:

"12БЛДЖАД!"
0

Тест Phantom
Цитата:

"123.345E-12"
1

Тест zombiee
Цитата:

"23.2gh465E-1"
0
"23.2465E-1"
1
"sdgf23.2465E-1"
0

Тест impersonalis2
Цитата:

"1+1"
0
"+.12E-008"
1
"+.12E-008.1"
0

Предлагаю собравшимся отписатсья (особенное если видят ошибки).
Функция, конечно позволяет вводить фантастические занчения мантиссы и показателя, но это вполне удовлетворяет моему ТЗ.

impersonalis 10.10.2009 18:26

Ответ: Проверка: является ли строка числом?
 
но блин, никто чет не заинтересовался

impersonalis 09.10.2010 23:32

Ответ: Проверка: является ли строка числом?
 
Кстати, по данному запросу в яндексе лидирует некий топик "Как лучше проверить, является ли строка числом?" (http://coder007.livejournal.com/568.html). Автор кторого отключил анонимные комменты. Так что рассмотрим его код здесь:
Код:

private static boolean checkBySteps(String string) {
        if (string == null || string.length() == 0) return false;

        int i = 0;
        if (string.charAt(0) == '-') i = 1;

        for (; i < string.length(); i++) {
            final char c = string.charAt(i);
            if (!(c >= '0' && c <= '9')) {
                return false;
            }
        }

        return true;
    }

Ну, во-первых, отцензуернный коммент ДядиДимы:
Цитата:

<<jimon>> (22:54:44 6/10/2010)
сишарпист думает о скорости ? нет пути
А во-вторых - мои "пять копеек" (сравнивая с кодом из поста #22).
Данный парсер не может корреткно отреагировать даже на "+1". Он реагирует только на целые числа, в записи которых отсутсвует десятичная степень (12Е3).
Ну это если кто будет лабы делать..

Morganolla 09.10.2010 23:59

Ответ: Проверка: является ли строка числом?
 
Цитата:

Сообщение от impersonalis (Сообщение 119598)
Требуется сабжевая фунЕция:
необходимо проверить - можно ли содержащийся в переданном указателе на начало нуль-терминированной строки текст интерпретировать как число, в соответствии со всякими там RFC. Не хочу изобретать велик. Но если грамотных реализаций нет - то могу и обойтись)

Блин, Ты по русски то нормально говори. Не в переданном указателе, а в переданном указателеМ ... ....текстЕ...
Тьфу ... вообще запутался... Текст , как таковой не содержится в указателе!!!
Надо было спросить так: "можно ли текст строки, которая передается через указатель..."

А то я блин ломаю голову!!! А С++ - очень точный язык.
ЗЫ . Проще свою функцию написать и не париться. Это и надежней будет!

Еще можно через потоковые классы. iostream. там есть возможность преобразовать из строки - число.

impersonalis 10.10.2010 00:11

Ответ: Проверка: является ли строка числом?
 
Цитата:

Блин, Ты по русски то нормально говори. Не в переданном указателе, а в переданном указателеМ ... ....текстЕ...
Угу - правка изначального варианта исказила смысл.
Изначально (по-русски!) имелось в виду:
текст, содержащийся в нуль-терминированной строке, указатель на которую был передан.
А не "в тексте, переданном указателем на строку". Что некорректно.
Цитата:

ЗЫ . Проще свою функцию написать и не париться. Это и надежней будет!
так и сделал - см пост номер 22
Цитата:

там есть возможность преобразовать из строки - число.
слабость такого подхода разбирается в теме. Функции трансляции либо игнорируют (обрезают) неинтерпретируемые куски (12ЙЙ=12), либо превращают их в ноль (0), что не явялется недопустимым выходом парсера (для "0"). iostream тут причём?

impersonalis 10.10.2010 00:16

Ответ: Проверка: является ли строка числом?
 
Morganolla харе править свой пост =) Мои ответы теряют актуальность.

impersonalis 20.10.2010 13:31

Ответ: Проверка: является ли строка числом?
 
В своё время не придал значению тому, что пустая строка ("") воспринимается как допустимое значение (подразумевая 0). При тестировании функции (точнее её реализации на Blitz3D) в полевых условиях с применением "эффекта кота" обнаружились (ВНЕЗАПНО?) дополнительные допустимые конструкции, которые уже с натяжкой можно списать на интеллектуальность парсера "строка->число". Исправляется всё просто.
Для проверки используется набор значений impersonalis-F1(FAIL-1):
Код:

E
(пустая строка)
+
-
.

Функция:
Код:

bool Check(char *s,int LEN){
        enum SymbolIs{DIGIT,EXP,SEP,SIGN,ETC};
        SymbolIs Key;
        int i;
        int Epos=-1;
        int Spos=-1;
        bool ExitFlg=true;
        bool IsClose=false;
        for(i=0;i<LEN && ExitFlg;i++){
                if(s[i]>='0' && s[i]<='9'){
                        Key=DIGIT;
                }
                else if(s[i]=='E' || s[i]=='e'){
                        Key=EXP;
                }
                else if(s[i]=='.' || s[i]==','){
                        Key=SEP;
                }
                else if(s[i]=='+' || s[i]=='-'){
                        Key=SIGN;
                }
                else{
                        Key=ETC;
                }
                IsClose=false;
                switch(Key){
                        case DIGIT:{
                                IsClose=true;
                                break;
                                          }
                        case EXP:{
                                if(Epos!=-1){
                                        ExitFlg=false;
                                        break;
                                }
                                Epos=i;
                                break;
                                        }
                        case SEP:{
                                if(Spos!=-1){
                                        ExitFlg=false;
                                        break;
                                }
                                Spos=i;
                                break;
                                        }
                        case SIGN:{
                                if(i==0 || Epos==i-1){
                                        break;
                                }
                                ExitFlg=false;
                                break;
                                          }
                        case ETC:{
                                ExitFlg=false;
                                break;
                                        }
                }
        }
        if(!IsClose){
                ExitFlg=false;
        }
        return ExitFlg;
}

Если закомментить строку сброса ExitFlg при лжи в IsClose функция вновь не проходит новый тест.
Код:

Test "SBJoker"
ололо  0
15445.1 1
Test "impersonalis"
12БЛДЖАД!      0
Test "Phantom"
123.345E-12    1
Test "zombiee"
23.2gh465E-1    0
23.2465E-1      1
sdgf23.2465E-1  0
Test "impersonalis-2"
1+1    0
+.12E-008      1
+.12E-008.1    0
Test "impersonalis-F1"
E      0
        0
+      0
-      0
.      0

Присылайте ваши наборы с аргументацией некорректности работы функции!

Phantom 18.06.2012 05:41

Ответ: Проверка: является ли строка числом?
 
Читал тут спецификацию JSON: http://www.json.org/json-ru.html
Увидел вот эту картинку: http://www.json.org/number.gif
Вспомнил эту тему, решил запостить.


Часовой пояс GMT +4, время: 16:41.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot