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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.80
stawerfar
141 / 55 / 4
Регистрация: 14.12.2010
Сообщений: 347
Записей в блоге: 1
#1

Как перевести из символа в число и после наоборот - C++

29.01.2012, 16:51. Просмотров 1855. Ответов 13
Метки нет (Все метки)

Доброго Вам времени суток форумчане! Сразу к делу.
Сталкнулся с проблемой в учебнике Лафоре есть пример //parse.cpp разбор арифметического выражения
Так вот я его собрался сделать но сам по своему. Вот что получилось:
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
#include<iostream>
#include<string>
#include<conio.h>
 
const int ciMAX = 100;
/**************************************************************************************************************/
//класс для представления стека, выражен в виде массива символов
class Stack
{
protected:
    char* ch_pt_steck;//указатель на массив символов т.е. стек
    int ipop;//вершина стека
public:
    //конструктор без параметров
    Stack(void):ipop(0)
    {
        ch_pt_steck = new char[ciMAX];//выделяю память под массив символов из 100 элементов
        ch_pt_steck[0]='~';
    }
    //конструктор с одним мапаметром
    explicit Stack(const char& cch_symbol)
    {
        Stack();//принудительный вызов конструтора без параметров для выдиления памяти для стека
        ch_pt_steck[ipop++]=cch_symbol;
    }
    //деструктор для освобождения памяти
    ~Stack(void)
    {delete[]ch_pt_steck;}
    //положить,толкнуть в кучу
    void push(const char& cch_symbol);
    //вытащить,вытолкнуть из кучи
    char pop(void);
    //получить размер стека
    int size(void);
};
 
//положить,толкнуть в кучу
void ::Stack:: push(const char& cch_symbol)
{   
    if(ipop<ciMAX-1)
    {
        ch_pt_steck[ipop++]=cch_symbol;
        ch_pt_steck[ipop]='\0';
    }
    else
    {
        std::cout<<"Стек полон!"<<std::endl;
    }
}
//вытащить,вытолкнуть из кучи
char ::Stack:: pop(void)
{
    if(ipop>0)
    {
        return (ch_pt_steck[--ipop]);
    
    }
    else
    {
        std::cout<<"Стек пуст!"<<std::endl;
    }
}
//получить размер стека
int ::Stack:: size(void)
{
    return (ipop);
}
 
/**************************************************************************************************************/
class express : private ::Stack
{
private:
    char* ch_pt_expression;//математическое выражение, арефметический пример
    int ilen;//длинна строки выражения
public:
    //конструктор без пареметров
    express(void):ilen(0),Stack()
    {
        setlocale(LC_ALL,"Russian");//разрешаю вывод русского язык
    }
    //конструктор с одним параметром
    express(char* ch_pt_exp);
    //десткруктор для освобождения памяти
    ~express(void)
    {delete []ch_pt_expression;}
    //первый круг анализа
    void the_first_aruond(void);
    //второй круг анализа
    void the_second_aruond(void);
    //вывод результата не экран
    char result(void);
    //получение выражения от пользователя
    void getexpress(void);
};
 
//конструктор с одним параметром
express::express(char* ch_pt_exp)
{
    express();//принудительный вызов конструктора без параметров для инициализации или обнуления значения полей класса
    ilen = strlen(ch_pt_exp);//получаю размер вырожения т.е. количесво содержащихся в нём символов
    ch_pt_expression = new char[ilen+1];//выделяю память достаточную для хранения выражения
    strcpy(ch_pt_expression,ch_pt_exp);//копирую выражение в поле класса
    ch_pt_expression[ilen]='\0';//задаю в ручную конец строки
 
}
void express:: the_second_aruond(void)
{
            char ch_number,ch_znak;
            while(size()!=1)
            {
                        ch_number = pop();//возвращаем чило
                        ch_znak = pop();//возвращаем знак операции
                        
                        switch(ch_znak)
                        {
                            case '+':
                                //превращаю символ-цифры в цифры произвожу операцию и пробразую обратно в символы
                                        push('0'+((pop()-'0')+(ch_number-'0')));
                                        break;
                            case '-':
                                
                                //превращаю символ-цифры в цифры произвожу операцию и пробразую обратно в символы
                                        push(((pop()-'0')-(ch_number-'0')));
                                        break;
                            case '*':
                                
                                //превращаю символ-цифры в цифры произвожу операцию и пробразую обратно в символы
                                        push('0'+((pop()-'0')*(ch_number-'0')));
                                        break;
                            case '/':
                                
                                //превращаю символ-цифры в цифры произвожу операцию и пробразую обратно в символы
                                        push('0'+((pop()-'0')/(ch_number-'0')));
                                        break;
                            default:
                                std::cout<<"Ошибка, неправильная арефметическаф операция ("<<ch_znak<<")"<<std::endl;
                                system("pause");//пауза для того чтобы пользователь прочитал сообщение об ошибке
                                exit(3);//аварийный выход из программы возвращающий системе 3
                        }
            }
}
//первый круг анализа
void express:: the_first_aruond(void)
{
    
    //начинаю разбор строки, арефметичекого выражения\
    здесь я буду просматривать арефметическое выражение символ за символом, выполняя при это не хитрые\
    операции:для начала я помещу в стек первый символ и первую орефметичекую операцию, после чего буду\
    смотреть на следующий символ, если это будет операция то буду сравнивать приоритеты текущей с предыдущей \
    оперецией- если предыдущая операция равна * или / а текущаа + или - то выполню предыдущую операцию \
    вытащив из стека соответствующие данные, если же предыдущаа операция + или - а текущаа * или \ то \
    ни чего ни делаю и продолжаю помещать данные в стек выполняя только те операции которые соответствуют\
    приведённому условию
    
    for(int i=0;i<ilen;i++)//разбор строки продолжается до тех пор пока не останется только одно чило
    {
        
        char ch_znak,ch_number;
            
            //помещаем число в стек
            if((ch_pt_expression[i] >='0'&& ch_pt_expression[i] <='9')&& i%2==0)//если символ число
            {push(ch_pt_expression[i]);}
            else if(!(ch_pt_expression[i] >='0'&& ch_pt_expression[i] <='9')&& i%2==0)
            {
                std::cout<<"Ошибка, введен не допустимый символ ("<<ch_pt_expression[i]<<")"<<std::endl;
                system("pause");//пауза для того чтобы пользователь прочитал сообщение об ошибке
                exit(1);//аварийный выход из программы возвращающий системе 1
            }
 
            //помещаем операцию в стек
            if((ch_pt_expression[i]== '+'|| ch_pt_expression[i]== '-'|| ch_pt_expression[i]=='*'|| ch_pt_expression[i]=='/')&& i!=0)
            {push(ch_pt_expression[i]);}
            else if(!(ch_pt_expression[i]== '+'|| ch_pt_expression[i]== '-'|| ch_pt_expression[i]=='*'|| ch_pt_expression[i]=='/')&& i%2!=0)
            {
                std::cout<<"Ошибка, введен не допустимая операция ("<<ch_pt_expression[i]<<")"<<std::endl;
                system("pause");//пауза для того чтобы пользователь прочитал сообщение об ошибке
                exit(2);//аварийный выход из программы возвращающий системе 2
            } 
            if(i>1)//если мы уже ввели первое число и символ
            {
                ch_number = pop();//возвращаем чило
                ch_znak = pop();//возвращаем знак операции
                //если следующая операция сложение или вычетание, то смело можно выполнять предыдущую операцию или
                //если прудыдущая и следующая операции умножения или диления то также выполняем предыдущую операцию
                if((ch_pt_expression[i+1]=='+'|| ch_pt_expression[i+1]== '-')||((ch_pt_expression[i+1]=='*'|| ch_pt_expression[i+1]== '/')&&(ch_znak == '*' || ch_znak == '/')))
                {
                        
                    switch(ch_znak)
                    {
                        case '+':
                            //превращаю символ-цифры в цифры произвожу операцию и пробразую обратно в символы
                                    push('0'+((pop()-'0')+(ch_number-'0')));
                                    break;
                        case '-':
                                
                            //превращаю символ-цифры в цифры произвожу операцию и пробразую обратно в символы
                                    push('0'+((pop()-'0')-(ch_number-'0')));
                                    break;
                        case '*':
                                
                            //превращаю символ-цифры в цифры произвожу операцию и пробразую обратно в символы
                                    push('0'+((pop()-'0')*(ch_number-'0')));
                                    break;
                        case '/':
                                
                            //превращаю символ-цифры в цифры произвожу операцию и пробразую обратно в символы
                                    push('0'+((pop()-'0')/(ch_number-'0')));
                                    break;
                        default:
                            std::cout<<"Ошибка, неправильная арефметическаф операция ("<<ch_znak<<")"<<std::endl;
                            system("pause");//пауза для того чтобы пользователь прочитал сообщение об ошибке
                            exit(3);//аварийный выход из программы возвращающий системе 3
                    }
                }//иначе помещаем всё обратно в стек
                else 
                {
                    push(ch_znak);//кладём обратно знак
                    push(ch_number);//кладём обратно число
                }
            }
            
    
    
    }
        the_second_aruond();//продолжение анализа
}
//вывод результата не экран
char express:: result(void)
{return (pop());}
//получение выражения от пользователя
void express:: getexpress(void)
{
    ilen=0;
    std::cout<<"Введите арифметическое выражение в виде 2+3*4/3-2\nЧисла должны быть из одной цифры\nНе используйте пробелы и скобки:";
    char ch_getche[2]={'d'};
    bool bflag=false;
    while(ch_getche[0]!=13)//продолжаем пока не встретим знак коретки т.е. пользователь не ражмёт enter
    {   
                ch_getche[0]=getche();
                char* ch_temp = new char[ilen+1];
                if(ilen!=0&&ch_getche[0]!=13)//если мы продолжаем вводить строчку то удаляю и перевыделяю память 
                {
                    
                    strcpy(ch_temp,ch_pt_expression);
                    delete []ch_pt_expression;
                    bflag=true;
                }
                
                if(ch_getche[0]!=13)
                {
                    
                    ilen++;//получаю размер вырожения т.е. количесво содержащихся в нём символов
                    ch_pt_expression = new char[ilen+1];//выделяю память достаточную для хранения выражения
                    ch_pt_expression[0]='\0';//задаю в ручную конец строки
                    if(bflag)
                    {bflag=false;strcpy(ch_pt_expression,ch_temp);}
                    strcat(ch_pt_expression,ch_getche);//склеиваю выражение символ за символом в поле класса
                    ch_pt_expression[ilen]='\0';//задаю в ручную конец строки
                }
                delete []ch_temp;
        
    }
    std::cout<<std::endl;
 
}
 
/**************************************************************************************************************/
 
int main(void)
{
    class ::express exp_val;
    //получаю значение от пользователя
    exp_val.getexpress();
    //вычисляю выражение
    exp_val.the_first_aruond();
    //вывожу результат
    std::cout<<"Рузультат : "<<exp_val.result()<<std::endl;
    
 
 
        system("pause");
    return 0;
}
ВСЁ нормально работает если вводить пример типа 4+1-2, или 7*5, НО НЕ РАБОТАЕТ КОГДА первым знаком операции идет сложение или вычетание а вторым диление или умножение : 9+6/3
Я ЗАМЕТИЛ вчём проблема но немогу понять как исправить положение , вроде все правильно делаю.
Если использовать пример типа 9+6/3 то символ 6 приабразуется в число , также и 3 преобразуется в число, после произходит правильное диление т.е. результат будет равет 2, далее 2 сложиться с числом 9 . А ВОТ РЕЗУЛЬТАТ ВСЕГО ВЫРАЖЕНИЯ Т.Е. 11 НЕ ПРЕОБРАЗУЕТСЯ ИЗ ЧИСЛА В СИМВОЛ В ИТОГЕ Я ПРОЛУЧАЮ СИМВОЛ ПО ТАБЛИЦЕ ASCII СИМВОЛ ПОД ДЕСЯТИЧНЫМ НОМЕРОМ 11
Помогите пожалуйста!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.01.2012, 16:51
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как перевести из символа в число и после наоборот (C++):

Перевести число из 2-ой системы в 10-тичную и наоборот - C++
Перевести число из 2-ой системы в 10-тичную и наоборот.(Желательно с алгоритмом)Заранее спасибо.

Перевести число из 4-ричной системы счисления в 18-ричную и наоборот - C++
Перевести число из 4-ричной системы счисления в 18-ричную и наоборот

Перевести код символа числа в число - C++
Как средствами с/с++ перевести код символа целого числа в само целое число? char ch; int num; ch = getche(); // в переменную...

Как char[] перевести в битовую маску long long(64 бита) и наоборот? - C++
Как char перевести в битовую маску long long(64 бита) и наоборот?

Перевести символ верхнего регистра в нижний и наоборот - C++
Подскажите, что не так: нужно введенную строку преобразовать так: символы верхнего регистра в символы нижнего регистра, и наоборот, а...

Вывод символа char, как код (как число) - C++
Привет. При выполнении: char ch = 'М'; cout &lt;&lt; hex &lt;&lt; uppercase &lt;&lt; (short) ch; выводится &quot;FFCC&quot;. Вопрос, как добится вывода...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
29.01.2012, 16:55 #2
atoi и itoa функции переводящие символы в числа и обратно
go
Эксперт C++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
29.01.2012, 17:10 #3
C++
1
boost::lexical_cast
stawerfar
141 / 55 / 4
Регистрация: 14.12.2010
Сообщений: 347
Записей в блоге: 1
29.01.2012, 17:16  [ТС] #4
Цитата Сообщение от go Посмотреть сообщение
C++
1
boost::lexical_cast
вот тут по подробней можно , что за библиотека и т.д.?

Добавлено через 3 минуты
Цитата Сообщение от AzaKendler Посмотреть сообщение
atoi и itoa функции переводящие символы в числа и обратно
Спасибо , но насколько я знаю эти функции принимают const char* а не char т.е. они работают со строками а не отдельно с одиночным символом
go
Эксперт C++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
29.01.2012, 17:21 #5
Цитата Сообщение от stawerfar Посмотреть сообщение
вот тут по подробней можно , что за библиотека и т.д.?
для работы с
C++
1
std::string
Цитата Сообщение от stawerfar Посмотреть сообщение
о насколько я знаю эти функции принимают const char* а не char т.е
C
1
2
char c = '5';
int dig = c - '0'; // dig == 5
stawerfar
141 / 55 / 4
Регистрация: 14.12.2010
Сообщений: 347
Записей в блоге: 1
29.01.2012, 17:27  [ТС] #6
Go
раз Вы мне предложили
C++
1
int dig = c - '0'; // dig == 5
то тогда подскажите почему
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
switch(ch_znak)
{
    case '+':
        //превращаю символ-цифры в цифры произвожу операцию и пробразую обратно в символы
                push('0'+((pop()-'0')+(ch_number-'0')));
                break;
    case '-':
                                
        //превращаю символ-цифры в цифры произвожу операцию и пробразую обратно в символы
                push(((pop()-'0')-(ch_number-'0')));
                break;
    case '*':
                                
        //превращаю символ-цифры в цифры произвожу операцию и пробразую обратно в символы
                push('0'+((pop()-'0')*(ch_number-'0')));
                break;
    case '/':
                                
        //превращаю символ-цифры в цифры произвожу операцию и пробразую обратно в символы
                push('0'+((pop()-'0')/(ch_number-'0')));
                break;
    default:
        std::cout<<"Ошибка, неправильная арефметическаф операция ("<<ch_znak<<")"<<std::endl;
        system("pause");//пауза для того чтобы пользователь прочитал сообщение об ошибке
        exit(3);//аварийный выход из программы возвращающий системе 3
}
не всегда работает. Если идти по отладке то в первый раз всё отлично работает , но в последующие разы самый последний результат не преобразует правильно...
go
Эксперт C++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
29.01.2012, 17:29 #7
Проверяйте содержимое буфера.
stawerfar
141 / 55 / 4
Регистрация: 14.12.2010
Сообщений: 347
Записей в блоге: 1
29.01.2012, 17:31  [ТС] #8
Что Вы имеете введу? Почитайте моё самое первое обращение.
diagon
Higher
1929 / 1195 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
29.01.2012, 18:15 #9
Цитата Сообщение от stawerfar Посмотреть сообщение
вот тут по подробней можно , что за библиотека и т.д.?
boost
Там вообще много полезных штуковин.
stawerfar
141 / 55 / 4
Регистрация: 14.12.2010
Сообщений: 347
Записей в блоге: 1
30.01.2012, 12:55  [ТС] #10
Люди!!! Я понял в чем ошибка у меня не получается норамльно перевести из числа в символ т.е.
C++
1
2
3
4
5
char ch1 = '3',ch2='2';
int i1=ch1 -'0' ,i2=ch1 -'0';
i1*=i2;//i1 = 6
//вот тут не получается !!! Как перевести обратно нужный в символ в данном случае '6'?
ch1 = i1+'0'//ch1 = "мусор "
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
30.01.2012, 14:27 #11
ну вообщето все работает. только не 6 а 9 там. в этом куске кода все норм,кроме пропущеной ;. ищи в других местах
stawerfar
141 / 55 / 4
Регистрация: 14.12.2010
Сообщений: 347
Записей в блоге: 1
30.01.2012, 15:48  [ТС] #12
Да спасибо я разобрался уже. Вся написанная мною программа рабочая я тупанул.Я так всё внутри устроил что программа работает номально то стчислами от 0 до 9 причем результат тоже должен быть в этих приделах!
Так как большие числа уже не один символ на несколько, а я использую буфер для хранения число один символ.
Всем ещё раз спасибо, за внимание!
go
Эксперт C++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
30.01.2012, 17:02 #13
Цитата Сообщение от stawerfar Посмотреть сообщение
i1*=i2;//i1 = 6
А не 9 ли здесь получиться?
stawerfar
141 / 55 / 4
Регистрация: 14.12.2010
Сообщений: 347
Записей в блоге: 1
30.01.2012, 17:28  [ТС] #14
Нет эти элементарные расчёты верны, вот они ещё раз для наглядности
C++
1
2
3
4
5
char ch1 = '3',ch2='2';
int i1=ch1 -'0' ,i2=ch2 -'0';
i1*=i2;//т.к i1= 3 а i2= 2 то выражение i1*=i2 тоже самое что и i1= i1*i2 следовательно i1 = 3 * 2
//вот тут не получается !!! Как перевести обратно нужный в символ в данном случае '6'?
ch1 = i1+'0'//ch1 = "мусор "
Но замечу что действительно на первой странице я допустил ошибку вот здесь
C++
1
2
3
char ch1 = '3',ch2='2';
int i1=ch1 -'0' ,i2=ch1 -'0';
i1*=i2;//i1=6 ОШИБКА I1 = 9
Потому что я продразумевал первый вариант а при наборе опечатался, точнее использовал "copy-past"
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.01.2012, 17:28
Привет! Вот еще темы с ответами:

Как после каждого 60-го символа сделать новый абзац? - C++
Как после каждого 60-го символа сделать новый абзац? Есть код, но он выводит только одну строчку с 60 символами. А в целом в файле 146...

Как вывести после запятой 3 символа включая нули - C++
Здравствуйте! Подскажите как вывести после запятой 3 символа включая нули! тип данных double!))) например! На входе: ...

Как перевести число с 10 в двоичную - C++
Ребята, помогите пожалуйста. Вот решил по практиковаться на С++, но ничего не получается. Как перевести число из 10 в 2-ичную систему. Буду...

Как перевести строку в число? - C++
есть строка вида 14-09-2015 надо перевести в дату как?


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
30.01.2012, 17:28
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru