Форум программистов, компьютерный форум CyberForum.ru

Моя реализация функции перевода string в int - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 22, средняя оценка - 4.73
sovaz1997
CEO SOVAZ Corp.
 Аватар для sovaz1997
379 / 225 / 2
Регистрация: 17.12.2011
Сообщений: 816
Записей в блоге: 1
21.12.2012, 18:23     Моя реализация функции перевода string в int #1
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <string>
 
using namespace std;
 
int str_to_int(string a);
 
int main() {
    string s = "-4789";
    cout << str_to_int(s);
}
 
int str_to_int(string a) {
    int num = 0;
    int tmp;
    bool anti = false;
 
    for(int i = a.size() - 1, l = 1; i >= 0; --i, l *= 10) {
        if(a[i] == '0') {tmp = 0;}
 
        else if(i == 0 && a[i] == '-') {anti = true;}
 
        else if(a[i] == '1') {tmp = 1;}
        else if(a[i] == '2') {tmp = 2;}
        else if(a[i] == '3') {tmp = 3;}
        else if(a[i] == '4') {tmp = 4;}
        else if(a[i] == '5') {tmp = 5;}
        else if(a[i] == '6') {tmp = 6;}
        else if(a[i] == '7') {tmp = 7;}
        else if(a[i] == '8') {tmp = 8;}
        else if(a[i] == '9') {tmp = 9;}
 
        else {
                return 0;
        }
 
        num += (tmp * l);
    }
 
    if(anti == true) {return -num;}
    else {return num;}
}


P.S. Пишите предложения по улучшению этой функции

Добавлено через 5 минут
Актуальна

Добавлено через 5 минут
Вверх
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.12.2012, 18:23     Моя реализация функции перевода string в int
Посмотрите здесь:

Существует ли метод/функция перевода значения символьной переменной в int C++
Функции float average(int arrray[],int from,int to) C++
string в int C++
int to string C++
C++ из int в string
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
22.12.2012, 16:11     Моя реализация функции перевода string в int #41
Цитата Сообщение от sovaz1997 Посмотреть сообщение
Моя реализация функции перевода string в int
Это не серьезно. Добавте системы счисление. Я когда-то strtol реализовывал. Могу код поискать.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4920 / 2663 / 243
Регистрация: 29.11.2010
Сообщений: 7,409
22.12.2012, 16:47     Моя реализация функции перевода string в int #42
Почему все так упорно игнорируют isdigit, isalpha?
ValeryS
Модератор
6374 / 4840 / 442
Регистрация: 14.02.2011
Сообщений: 16,043
22.12.2012, 21:09     Моя реализация функции перевода string в int #43
и так поехали
Цитата Сообщение от fit Посмотреть сообщение
зачем лезть в асм. все проверяется куда проще:
"Пастернака не читал но осуждаю"
Цитата Сообщение от fit Посмотреть сообщение
как видишь, никакого \0 в памяти после двойки нет,
во первых какой компилятор? во вторых в каком режиме?
Цитата Сообщение от fit Посмотреть сообщение
думаю, на этом спор исчерпан.
нет он только начинается
еще раз
во первых какой компилятор? во вторых в каком режиме?
никто не гарантировал что вокруг памяти будут 0 но у ТС срабатывает эта строка
C++
1
int m=atoi(buf);
значит никакого мусора нет (иначе бы ноль вернула)
Цитата Сообщение от fit Посмотреть сообщение
это делается не "занулением". new резервирует необходимое кол-во байт в незанятой памяти. компилятор это число запоминает и при попытке изменить значение ячейки ОП вне выделенного числа байт выдает ошибку.
хотелось бы верить но в жизни все не так
в отладочном режиме ты выделяешь 100 байт а выделяется 200(к примеру) и сверху и снизу есть защитный буфер при обращении к которому вызывается исключение
в режиме реализации ничего такого нет, поэтому можно получить странное поведение
еще раз если ты что то утверждаешь приводи ассемблерные листинги(хотя бы для одного конкретного компилятора)

Цитата Сообщение от fit Посмотреть сообщение
это делается не "занулением". new резервирует необходимое кол-во байт в незанятой памяти. компилятор это число запоминает и при попытке изменить значение ячейки ОП вне выделенного числа байт выдает ошибку.
ссылку в листинге, а не свои размышления.
где он их запоминает? формат памяти в дампах?

Цитата Сообщение от fit Посмотреть сообщение
она работает не потому что ch терминирован '\0', а потому что:
1. atoi игнорирует символы, не являющиеся числом.
и смело возвращает 0
Цитата Сообщение от fit Посмотреть сообщение
сканирует память до первого встретившегося \0. а он рано или поздно там встретиться. только вот сколько ему придется прочитать для этого байт - черт его знает. вот чтобы не пришлось читать лишнюю память, в спецификации и требуется \0 в конце.
спасибо что ты напомнил мне как устроена строка в С
Цитата Сообщение от fit Посмотреть сообщение
статическая char строка терминуется \0 всегда. это стандарт языка. и лежит она в программном стеке, а не куче, где работает new.
еще раз спасибо
в общем давайте спорить о вкусе устриц с теми хоть однажды их ел
кстати ты не ответил на такой вопрос
Цитата Сообщение от ValeryS Посмотреть сообщение
C++
1
2
3
4
5
6
7
char *buf=new char[5];
buf[0]='5';
buf[1]='3';
buf[2]=0;
buf[3]='6';
buf[4]='7';
int m=atoi
(buf);
выделено 5 байт
посредине я вставил 0 т.е строка всего три байта
что выдаст atoi?
по твоей логике 5367( я же пять байт выделил)
по моей 53( строка кончилась)


Цитата Сообщение от fit Посмотреть сообщение
статическая char строка терминуется \0 всегда.
Цитата Сообщение от fit Посмотреть сообщение
к тому же, atoi получит ровно столько, сколько зарезервировал new.
противоречия не чествуем?
в статике нет new
sovaz1997
CEO SOVAZ Corp.
 Аватар для sovaz1997
379 / 225 / 2
Регистрация: 17.12.2011
Сообщений: 816
Записей в блоге: 1
22.12.2012, 21:22  [ТС]     Моя реализация функции перевода string в int #44
Актуальна
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
22.12.2012, 21:31     Моя реализация функции перевода string в int #45
Цитата Сообщение от ValeryS Посмотреть сообщение
и смело возвращает 0
Ну не совсем. Если были до буквенного символа цифры, то возвращается то самое число. Например строка "123b123" вернет число 123. Так же игнорируются первые пробельные символы. Например строка " \t 123b123" вернет все тоже число 123. Ну и само собой засчитывается символы + и -, если они перед первой цифрой стоят.
BRcr
 Аватар для BRcr
4003 / 2292 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
22.12.2012, 23:02     Моя реализация функции перевода string в int #46
sovaz1997, это соц-исследование какое-то что ли? Зачем понукаешь?
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
22.12.2012, 23:13     Моя реализация функции перевода string в int #47
Вот писал на чистом Си(не С99)

<ctype.h> не юзал.
Только функции ввода/вывода.
<stdlib.h> для system();

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <stdio.h>
#include <stdlib.h>
 
long strtol (char *, char **, int );
double pow (double , int );
 
#define isdigit(a) ((a) >= '0' && (a) <= '9') 
#define tolower(a) ((a) >= 'A' && (a) <= 'Z' ? (a) - 'A' + 'a' : (a)  )
#define isalpha(a) ( ((a) >= 'A' && (a) <= 'Z') || ((a) >= 'a' && (a) <= 'z')  ? (a) : 0 )
 
int main (void)
{
    char s[] = "021 10x 0xff";
    char *p;
 
    printf ("%ld\n", strtol (s, &p, 8) );
    printf ("%ld\n", strtol ("101", &p, 2) );
    printf ("%ld\n", strtol ("125", &p, 10) );
    printf ("%ld\n", strtol ("0x5Ab", &p, 16) );
    printf ("%ld\n", strtol ("5Ab", &p, 16) );
    system ("pause");
    return 0;
}
 
long strtol (char *s, char **end, int base)
{
    long res = 0L;
    char *p;
    int exp;
 
    if ( s && *s )
    {
        for ( ; *s && !isdigit(*s) && !isalpha (*s) ; ++s )
            ;
        for ( *end = s ; **end && **end - '0' < base && isdigit (**end) ; ++*end ) 
            ;
    }
    else 
    {
        *end = NULL;
        return res;
    }
 
    if ( base )
        if ( base >= 2 && base <= 36 ) 
        {
            if ( base > 10 ) // dvigaen *end do konca
                for ( ; **end && tolower(**end) - 'a' + 10 < base && isalpha(**end) ; ++**end )
                    ;
            //Run
            for ( p = *end - 1, exp = 0 ; p != (s - 1) ; --p )
                res +=  (isalpha (*p) ? tolower(*p) - 'a' + 10 : *p - '0') * (long) pow ( (double) base, exp++ );// Zde
        }
        else
        {
            // ERROR ret 0L
        }
    else
    {
        //Standart 0x 1123 
        // else ret 0L 
        if ( tolower(*(s + 1)) == 'x' ) // !!!!!!!!!!!WRONG!!!!!!!!!!
            res = strtol ( s + 2, end, 16 );                
    }
    return res;
}
 
double pow( double base, int exp )
{
    size_t i;
    double res = 1;
 
    if ( exp < 0 )
        res = pow ( 1 / base , -1 * exp );
    else
    {
        for ( i = 0 ; i < (size_t) exp ; ++i )
            res *= base;
    }
    return res;
}
Согласен вариант не очень, но писалась давно нет желания допиливать.
Если будут конфликтовать идентификаторы, то либо компилить с другими ключами, либо добавить макросы.
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4920 / 2663 / 243
Регистрация: 29.11.2010
Сообщений: 7,409
22.12.2012, 23:22     Моя реализация функции перевода string в int #48
go, у меня конфликтует с strtol из stdlib.h (minGW)
Комменты точно в "грязном С".

Добавлено через 4 минуты
И если убрать комменты, stdlib.h и system, то крах после вывода значений.
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
22.12.2012, 23:42     Моя реализация функции перевода string в int #49
MrGluck, угу. В GCC Segmentation fault. Если есть возможность, запусти в Visual Studio 2010. Писал именно там, где-то видно с указателями напутал. Правда, нет ни интереса, ни времени исправлять.
Dani
1263 / 621 / 50
Регистрация: 11.08.2011
Сообщений: 2,236
Записей в блоге: 2
Завершенные тесты: 1
23.12.2012, 01:01     Моя реализация функции перевода string в int #50
go, я попробовал реализовать перевод из одной СС в другую, можете посмотреть?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <string>
#include <cmath>
#include <cctype>
#include <algorithm>
 
 
void UpperCase (std::string::iterator a, std::string::iterator b)
{
    while (a != b)
    {
        *a = toupper (*a);
        ++a;
    }
}
 
 
std::string Process (std::string s, int start, int finish)
{
    if (start < 2 || finish < 2)
        return ("Wrong Start or Finish CC!");
 
    int ans = 0, tmp, b = -1;
    UpperCase (s.begin(), s.end());
    //To 10 CC
    for (int i=s.length()-1; i >= 0; --i)
    {
        if ( isdigit(s[i]) )
            tmp = s[i] - '0';
        else
            tmp = s[i] - 'A' + 10;
 
        ans += tmp * pow (start + .0, ++b);
    }
 
    //From 10 CC
    std::string a;
    if (!ans) 
        a = '0';
    else
        while (ans)
        {
            if (ans % finish <= 9)
                a += (char(ans % finish + '0'));
            else
                a += (char(ans % finish - 10 + 'A'));
            ans /= finish;
        }
        std::reverse (a.begin(), a.end());
    return a;
}
 
int main()
{
    std::string str;
    int s, f;
 
    std::cout << "Enter Number: ";
    std::cin >> str;
    std::cout << "Enter start and end CC: ";
    std::cin >> s >> f;
 
    std::cout << Process (str, s, f) << std::endl;
    system ("pause");
    return 0;
}
fit
14 / 14 / 0
Регистрация: 20.04.2010
Сообщений: 102
23.12.2012, 06:48     Моя реализация функции перевода string в int #51
Цитата Сообщение от ValeryS
"Пастернака не читал но осуждаю"
да я-то с ним знаком, только зачем так все усложнять ежели и так все под носом
Цитата Сообщение от ValeryS
нет он только начинается
еще раз
во первых какой компилятор? во вторых в каком режиме?
VS2010. и в runtime и в debug после двойки мусор. cout же это наглядно поясняет и без отладчика.
Кликните здесь для просмотра всего текста

Цитата Сообщение от ValeryS
никто не гарантировал что вокруг памяти будут 0 но у ТС срабатывает эта строка
C++
1
int m=atoi(buf);
значит никакого мусора нет (иначе бы ноль вернула)
читаем спецификацию функции и таки прекращаем спор
еще раз, на пальцах объясню, каким чудом это работает в нашем случае:
1. atoi начинает сканировать строку. видит, первый символ - число. все нормально, сканирует дальше.
2. видит, 2ой элемент массива не число (мусор пошел). игнорирует его - завершает разбор. переводит найденную до того цифру к int и возвращает значение.
3. 0 atoi возвращает ежели в переданном массиве не встретилось вообще ни одного числа, либо перед цифрами имелся не числовой символ (за исключением \t, +, -)
в общем, мифические "зануления" здесь не причем.

Цитата Сообщение от ValeryS
ссылку в листинге, а не свои размышления.
где он их запоминает? формат памяти в дампах?
это я во всякой разной литературе читал, когда писал компилятор. так-то сейчас специально уточнил и вот что обнаружил: конкретно в с++ контроль за выходом за границы динамического массива вообще отсутствует.
подтверждаю рабочим примером:
C++
1
2
int* f = new int[5];
f[6]=7;
проверьте - ни разу не ругнется на выход за пределы памяти, никаких исключений. ни в runtime, ни в debug. еще один аргумент, что никакого "зануления" в целях отлова как оказалось мифической для плюсов ошибки не существует.

Цитата Сообщение от ValeryS
в отладочном режиме ты выделяешь 100 байт а выделяется 200(к примеру) и сверху и снизу есть защитный буфер при обращении к которому вызывается исключение
в режиме реализации ничего такого нет, поэтому можно получить странное поведение
еще раз если ты что то утверждаешь приводи ассемблерные листинги(хотя бы для одного конкретного компилятора)
1. этоn буфер принудительно зануляется? нет, я конечно сейчас не могу отрицать его существование. но у меня большие сомнения, что там именно нули. а это важно.
2. почему примеры говорят об обратном? ну не видит VS никаких исключений, а мусор видит и массивы за границей памяти спокойно инициализирует. и я не полезу в ассемблер дабы это проверять, потому как пока что верю своим глазам и таки знаю стандарты.

Цитата Сообщение от ValeryS
выделено 5 байт
посредине я вставил 0 т.е строка всего три байта
что выдаст atoi?
по твоей логике 5367( я же пять байт выделил)
по моей 53( строка кончилась)
atoi ведет разбор до первого нечислового символа. в идеале это нулевой байт \0. в реалиях что угодно не числовое.

Цитата Сообщение от ValeryS
противоречия не чествуем?
в статике нет new
с new я видимо неправильно сформулировал свою мысль. не имелось ввиду, что передается к примеру 5 байт, что new зарезервировал. конечно же передается только указатель (адрес на 1 элемент).
мной имелось ввиду, что динамический char массив не терминуется нулем при его инициализации. new инициализирует ровно столько байт, сколько нужно для размещения переданного аргумента.
про статику. видимо невнимательно читаешь, либо специально делаешь из меня дурака.
конструкция:
C++
1
char* ch = "abcd"
неявно терминует \0 строку abcd в конце. вот тут-то, в статике, есть этот \0, который не мы "не видим". при инициализации через new \0 не существует.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
23.12.2012, 07:23     Моя реализация функции перевода string в int #52
Цитата Сообщение от fit Посмотреть сообщение
подтверждаю рабочим примером:
C++
1
2
int* f = new int[5];
f[6]=7;
проверьте - ни разу не ругнется на выход за пределы памяти, никаких исключений. ни в runtime, ни в debug. еще один аргумент, что никакого "зануления" в целях отлова как оказалось мифической для плюсов ошибки не существует.
VS 2010? Если есть delete[] f; то вроде должен ругаться в дебаге.
BRcr
 Аватар для BRcr
4003 / 2292 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
23.12.2012, 11:23     Моя реализация функции перевода string в int #53
Цитата Сообщение от fit Посмотреть сообщение
проверьте - ни разу не ругнется на выход за пределы памяти, никаких исключений. ни в runtime, ни в debug. еще один аргумент, что никакого "зануления" в целях отлова как оказалось мифической для плюсов ошибки не существует.
Зануления нет, конечно - это было бы крайне неэффективно.
Но вот шариться за пределами выделенной памяти получится лишь до поры до времени, пока не попытаешься модифицировать чужой выделенный кусок.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
23.12.2012, 11:31     Моя реализация функции перевода string в int #54
Цитата Сообщение от BRcr Посмотреть сообщение
Но вот шариться за пределами выделенной памяти получится лишь до поры до времени, пока не попытаешься модифицировать чужой выделенный кусок.
Да легко.

Это Си++. Один из его императивов: не мешать творить что угодно, если этого явно просят. Поэтому в стандарте обращение к невыделенной памяти описано как UB. Можно это делать, но под свою ответственность.

Поэтому никакие проверки выделенности не обязаны выполняться, если самостоятельно их не выполнять. Это может быть как использование аналога обёртки над std::vector с проверкой границ, так и запуск программы под каким-нибудь Валгриндом.

Максимум операционка по носу даст сегфолтом за обращения к невыделенным страницам, но и то, она может это не делать, и buffer overflow в пределах страницы это не детектит.
BRcr
 Аватар для BRcr
4003 / 2292 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
23.12.2012, 12:12     Моя реализация функции перевода string в int #55
А я о чем? Можно, если осторожно. Еще DEP, если соответственно включен, будет рубить поползновения к чужой памяти.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
23.12.2012, 12:21     Моя реализация функции перевода string в int #56
Нельзя просто так получить доступ к чужой памяти. Не такими способами как Вы думаете. new ( malloc и другие аллокаторы ) часто выделяют память с запасом. Вот по этому запасу и удается беспроблемно гулять, потому что это память размечена ОС для вашей программы. Вот дальше этой памяти уже идет не размеченная область. Она никуда не указывает, эти адреса виртуального пространства просто напросто не связаны ОС с физическими адресами памяти. При доступе к ним ( чтение/запись ) программа просто падает. Так же можно без проблем гулять и по памяти, которая была выделена при запуске ( стек, глобальные/статические переменные ).
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
23.12.2012, 13:48     Моя реализация функции перевода string в int #57
Цитата Сообщение от Dani Посмотреть сообщение
go, я попробовал реализовать перевод из одной СС в другую, можете посмотреть?
В принципе все логично.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.12.2012, 15:06     Моя реализация функции перевода string в int
Еще ссылки по теме:

Моя реализация функции перевода STRING в DOUBLE C++
Функция isspace и тип string: Не существует подходящей функции преобразования из "std::string" в "int" C++
Не существует подходящей функции преобразования из "std::string" в "int" C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
sovaz1997
CEO SOVAZ Corp.
 Аватар для sovaz1997
379 / 225 / 2
Регистрация: 17.12.2011
Сообщений: 816
Записей в блоге: 1
23.12.2012, 15:06  [ТС]     Моя реализация функции перевода string в int #58
Актуальна
Yandex
Объявления
23.12.2012, 15:06     Моя реализация функции перевода string в int
Ответ Создать тему

Метки
atoi, int, itoa, string
Опции темы

Текущее время: 13:17. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru