CEO SOVAZ Corp.
 Аватар для sovaz1997
386 / 232 / 51
Регистрация: 17.12.2011
Сообщений: 822
Записей в блоге: 1

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

21.12.2012, 18:23. Показов 8759. Ответов 57

Студворк — интернет-сервис помощи студентам
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 минут
Вверх
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.12.2012, 18:23
Ответы с готовыми решениями:

Моя реализация функции перевода STRING в DOUBLE
#include &lt;iostream&gt; #include &lt;string&gt; using namespace std; double str_to_double(string a); int main() { string s =...

Реализация функции char *padl(const char *string, int len, int c=' ')
Реализовать функцию возвращающую указатель на новую строку длины len, полученную из string либо удалением лишних символов слева , либо...

Моя реализация алгоритма перевода числа в пропись (русский язык)
Добрый день.Недавно передо мной стояла задача сделать REST сервис перевода числа в пропись(на русском языке).Я хочу,чтобы мой код...

57
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
22.12.2012, 16:11
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от sovaz1997 Посмотреть сообщение
Моя реализация функции перевода string в int
Это не серьезно. Добавте системы счисление. Я когда-то strtol реализовывал. Могу код поискать.
1
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
22.12.2012, 16:47
Почему все так упорно игнорируют isdigit, isalpha?
1
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,874
22.12.2012, 21:09
и так поехали
Цитата Сообщение от 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
1
CEO SOVAZ Corp.
 Аватар для sovaz1997
386 / 232 / 51
Регистрация: 17.12.2011
Сообщений: 822
Записей в блоге: 1
22.12.2012, 21:22  [ТС]
Актуальна
0
 Аватар для Toshkarik
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
22.12.2012, 21:31
Цитата Сообщение от ValeryS Посмотреть сообщение
и смело возвращает 0
Ну не совсем. Если были до буквенного символа цифры, то возвращается то самое число. Например строка "123b123" вернет число 123. Так же игнорируются первые пробельные символы. Например строка " \t 123b123" вернет все тоже число 123. Ну и само собой засчитывается символы + и -, если они перед первой цифрой стоят.
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
22.12.2012, 23:02
sovaz1997, это соц-исследование какое-то что ли? Зачем понукаешь?
1
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
22.12.2012, 23:13
Вот писал на чистом Си(не С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;
}
Согласен вариант не очень, но писалась давно нет желания допиливать.
Если будут конфликтовать идентификаторы, то либо компилить с другими ключами, либо добавить макросы.
1
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
22.12.2012, 23:22
go, у меня конфликтует с strtol из stdlib.h (minGW)
Комменты точно в "грязном С".

Добавлено через 4 минуты
И если убрать комменты, stdlib.h и system, то крах после вывода значений.
0
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
22.12.2012, 23:42
MrGluck, угу. В GCC Segmentation fault. Если есть возможность, запусти в Visual Studio 2010. Писал именно там, где-то видно с указателями напутал. Правда, нет ни интереса, ни времени исправлять.
0
1406 / 648 / 135
Регистрация: 11.08.2011
Сообщений: 2,299
Записей в блоге: 2
23.12.2012, 01:01
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;
}
0
14 / 14 / 1
Регистрация: 20.04.2010
Сообщений: 102
23.12.2012, 06:48
Цитата Сообщение от 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 не существует.
0
What a waste!
 Аватар для gray_fox
1612 / 1304 / 180
Регистрация: 21.04.2012
Сообщений: 2,735
23.12.2012, 07:23
Цитата Сообщение от fit Посмотреть сообщение
подтверждаю рабочим примером:
C++
1
2
int* f = new int[5];
f[6]=7;
проверьте - ни разу не ругнется на выход за пределы памяти, никаких исключений. ни в runtime, ни в debug. еще один аргумент, что никакого "зануления" в целях отлова как оказалось мифической для плюсов ошибки не существует.
VS 2010? Если есть delete[] f; то вроде должен ругаться в дебаге.
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
23.12.2012, 11:23
Цитата Сообщение от fit Посмотреть сообщение
проверьте - ни разу не ругнется на выход за пределы памяти, никаких исключений. ни в runtime, ни в debug. еще один аргумент, что никакого "зануления" в целях отлова как оказалось мифической для плюсов ошибки не существует.
Зануления нет, конечно - это было бы крайне неэффективно.
Но вот шариться за пределами выделенной памяти получится лишь до поры до времени, пока не попытаешься модифицировать чужой выделенный кусок.
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
23.12.2012, 11:31
Цитата Сообщение от BRcr Посмотреть сообщение
Но вот шариться за пределами выделенной памяти получится лишь до поры до времени, пока не попытаешься модифицировать чужой выделенный кусок.
Да легко.

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

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

Максимум операционка по носу даст сегфолтом за обращения к невыделенным страницам, но и то, она может это не делать, и buffer overflow в пределах страницы это не детектит.
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
23.12.2012, 12:12
А я о чем? Можно, если осторожно. Еще DEP, если соответственно включен, будет рубить поползновения к чужой памяти.
0
 Аватар для Toshkarik
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
23.12.2012, 12:21
Нельзя просто так получить доступ к чужой памяти. Не такими способами как Вы думаете. new ( malloc и другие аллокаторы ) часто выделяют память с запасом. Вот по этому запасу и удается беспроблемно гулять, потому что это память размечена ОС для вашей программы. Вот дальше этой памяти уже идет не размеченная область. Она никуда не указывает, эти адреса виртуального пространства просто напросто не связаны ОС с физическими адресами памяти. При доступе к ним ( чтение/запись ) программа просто падает. Так же можно без проблем гулять и по памяти, которая была выделена при запуске ( стек, глобальные/статические переменные ).
0
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
23.12.2012, 13:48
Цитата Сообщение от Dani Посмотреть сообщение
go, я попробовал реализовать перевод из одной СС в другую, можете посмотреть?
В принципе все логично.
1
CEO SOVAZ Corp.
 Аватар для sovaz1997
386 / 232 / 51
Регистрация: 17.12.2011
Сообщений: 822
Записей в блоге: 1
23.12.2012, 15:06  [ТС]
Актуальна
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.12.2012, 15:06
Помогаю со студенческими работами здесь

Too few parameters in call to 'Lechebnica::AddNewElement(int,int,string,string,int,string)
Edit1 Id Edit2 Имя Edit3 Фамилия Edit4 Номер телефона ComboBox1 Услуга Всё string, кроме id, оно int ...

Метод int MmPp(string str) для перевода строковой даты в число
Написать метод int MmPp(string str) {} Параметром является дата в виде &quot;21.mai&quot; (число, точка, пробел, название месяца текстом). ...

Создайте класс Animal. Добавьте поля string Name, string Kind, string Areal, int Population
Здравствуйте! По C# есть задачка, с которой я так и не разобрался :( Задача: Создайте класс Animal. Добавьте поля string...

Создайте класс Animal. Добавьте поля string Name, string Kind, string Areal, int Population
Создайте класс Animal. Добавьте поля string Name, string Kind, string Areal, int Population. Создание объектов может происходить как без...

Функция isspace и тип string: Не существует подходящей функции преобразования из "std::string" в "int"
Добрый день! Я только начинаю изучать язык c++ по книге &quot;Язык программирования С++. Базовый курс 5-е изд 2014(Стэнли Б....


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

Или воспользуйтесь поиском по форуму:
58
Ответ Создать тему
Опции темы

Новые блоги и статьи
Debian 13: Установка Lazarus QT5
ВитГо 09.05.2026
Эта инструкция моя компиляция инструкций volvo https:/ / www. cyberforum. ru/ blogs/ 203668/ 10753. html и его же старой инструкции по установке Lazarus с gtk2. . .
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru