Задача Преобразовать строку символов в соответствующее число и обратно.
При составлении программ часто возникает задача получения данных, например, введенных в поле редактирования в числовой форме и вывод результата в текстовое поле. Число, которое принимает участие в вычислительных процедурах, должно быть представлено в виде строки символов, понятных пользователю, для вывода на экран.
Например, число 235 состоит из трех символов — ‘2’, ‘3’, ‘5’. Целью рассмотрения данной задачи является приведение символьной строки к соответствующему ей числовому виду.
Для этого нужно разбить символьную строку на значащие разряды и выбрать цифры, соответствующие каждому значащему разряду.
Каждый символ цифры имеет соответствующий ему код в базовой таблице кодировки:
Символ цифры | Десятичный код | Шестнадцатеричный код | Двоичный код |
0 | 48 | 0x30 | 0011 0000 |
1 | 49 | 0x31 | 0011 0001 |
2 | 50 | 0x32 | 0011 0010 |
3 | 51 | 0x33 | 0011 0011 |
4 | 52 | 0x34 | 0011 0100 |
5 | 53 | 0x35 | 0011 0101 |
6 | 54 | 0x36 | 0011 0110 |
7 | 55 | 0x37 | 0011 0111 |
8 | 56 | 0x38 | 0011 1000 |
9 | 57 | 0x39 | 0011 1001 |
В соответствии с приведенной таблицей, значащая часть каждого символа цифры содержится в младшей тетраде битов (младших четырех разрядах). Для получения цифры, соответствующей символу, достаточно произвести операцию: n = s & 0x0F; где n — значащая цифра, s — символ цифры. Маска 0x0F позволяет оставить только младшие 4 значащих разряда. Старшие 4 разряда становятся равны 0.
При решении обратной задачи — представления числа в виде текстовой строки — каждая цифра значащего разряда преобразуется в соответствующий ей символ с помощью операции: s = n | 0x30; Указанная операция добавляет двоичное значение 0011 в старшие 4 разряда, тем самым формируя код символа из соответствующей значащей цифры.
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
#include <iostream>
using namespace std;
// Функция преобразования строки в число
int StrToInt(char* s)
{
int temp = 0; // число
int i = 0;
int sign = 0; // знак числа 0- положительное, 1 — отрицательное
if (s[0] == '-')
{
sign = 1;
i++;
}
while (s[i] >= 0x30 && s[i] <= 0x39)
{
temp = temp + (s[i] & 0x0F);
temp = temp * 10;
i++;
}
temp = temp / 10;
if (sign == 1)
temp = -temp;
return(temp);
}
// Функция преобразования числа в строку
char* IntToStr(int n)
{
char s[40], t, * temp;
int i, k;
int sign = 0;
i = 0;
k = n;
if (k < 0)
{
sign = 1;
k = -k;
}
do
{
t = k % 10;
k = k / 10;
s[i] = t | 0x30;
i++;
} while (k > 0);
if (sign == 1)
{
s[0] = '-';
i++;
}
temp = new char;
k = 0;
i--;
while (i >= 0)
{
temp[k] = s[i];
i--;
k++;
}
temp[k] = '\0';
return(temp);
}
// Проверка выполнения
int main()
{
int num;
char s[40], * n;
system("chcp 1251");
system("cls");
cout << "Введите число: ";
cin.getline(s, 80);
num = StrToInt(s);
cout << "Вы ввели число " << num;
num = num + 1;
n = IntToStr(num);
cout << endl << "увеличенное на 1 число равно " << n;
cin.get();
return 0;
}

Преобразовал
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
signed long long pcsznumber(const char* str) {
bool sign = *str == '-';
signed long long result = 0;
while (*str)
if (!(*str < '0' || *str > '9')) {
result += (*str++ & 0x0F);
if (*str) result *= 10;
}
if (sign) return -result;
else return result;
}
// Создаёт строковой формат числа в куче и возвращает указатель на строку в стиле С
const char* numbercsz(signed long long number) {
char* result = new char[21], *index = result;
if (number < 0) *index++ = '-';
while (number > 0) {
*index++ = (number % 10) | '0';
number /= 10;
}
char* end = result + 21;
while (index != end) *index++ = '\0';
return(result);
}
Поспешил, была ошибка вычисления с отрицательными числами, но теперь всё работает как нужно.
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
signed long long pcsznumber(const char* str) {
bool sign = *str == '-';
if (sign) ++str;
signed long long result = 0;
while (*str)
if (!(*str < '0' || *str > '9')) {
result += (*str++ & 0x0F);
if (*str) result *= 10;
}
if (sign) return -result;
else return result;
}
// Создаёт строковой формат числа в куче и возвращает указатель на строку в стиле С
const char* numbercsz(signed long long number) {
char* result = new char[21], *index = result;
if (number < 0) {
*index++ = '-';
number = -number;
}
while (number > 0) {
*index++ = (number % 10) | '0';
number /= 10;
}
char* end = result + 21;
while (index != end) *index++ = '\0';
return(result);
}
строку "temp = temp * 10;" стоит поднять выше
строки "temp = temp + (s & 0x0F);", тогда ненужна будет
эта строка "temp = temp / 10;"
поэтому стоит заменить, это
2
3
4
5
6
7
{
temp = temp + (s[i] & 0x0F);
temp = temp * 10;
i++;
}
temp = temp / 10;
на это
2
3
4
5
6
7
{
temp = temp * 10;
temp = temp + (s[i] & 0x0F);
i++;
}
//temp = temp / 10;
в программе выводы строки в число, вы ведь не учитываете переполнение, если в строке забито число большее типа int?
Не учитываю
s = t | 0x30; // что означает t | 0x30; ???
0x30=48;
0x30 — это код символа 0