Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
15 / 0 / 0
Регистрация: 29.11.2009
Сообщений: 26
1

класс "Символьные числа". поправить код

21.04.2010, 18:45. Показов 1072. Ответов 2
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Имеется реализация класса символьных чисел. В принципе, должен работать на ура. Но выдает три ошибки:
[Linker Error] Unresolved external 'strnum::strnum()' referenced from UNIT1.OBJ
[Linker Error] Unresolved external 'strnum::~strnum()' referenced from UNIT1.OBJ
[Linker Error] Unresolved external 'TForm1::' referenced from PROJECT1.OBJ

Поправьте пожалуйста, где что не так, тело класса ниже:

stringnumber.h
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
#ifndef stringnumberH
#define stringnumberH
#endif
#include <vcl.h>
 
class strnum{
    private:
    bool flag;                          // знак числа, true если отрицательное
    AnsiString string;                  // строка, содержащая число
    int dot();                              // позиция точки
    strnum falsedel(strnum &Qs);        // вспомогательное деление вычитанием
    strnum addzero(int k);                          // дописывает нули спереди
    strnum addzerob(int k);                         // дописывает нули сзади
    strnum cutzero(void);                           // убирает лишние нули
    public:
    strnum();                               // пустой конструктор
    strnum(const strnum & Qs);          // конструктор копирования
    strnum(int Qs);                         // конструктор от целого числа
    strnum(char* Qs);                   // конструктор от строки
    strnum(double Qs);                  // конструктор от вещественного
    ~strnum();                              // деструктор
    strnum strnum::operator =(strnum Qs);       // присваивание
    strnum strnum::operator =(int Qs);
    strnum strnum::operator =(double Qs);
    strnum strnum::operator =(char* Qs);
    strnum strnum::operator +(strnum &Qs);      // сложение
    strnum strnum::operator +(int Qs);
    strnum strnum::operator +(double Qs);
    strnum strnum::operator -();                    // меняем знак (умножение на -1)
    strnum strnum::operator -(strnum &Qs);      // вычитание
    strnum strnum::operator -(int Qs);
    strnum strnum::operator -(double Qs);
    strnum strnum::operator *(int Qs);          // умножение
    strnum strnum::operator *(strnum &Qs);
    strnum strnum::operator *(double Qs);
    strnum strnum::operator /(strnum &Qs);      // деление
    strnum strnum::operator /(int Qs);  
    strnum strnum::operator /(double Qs);
       AnsiString astext();                             // выводит число как текст
};
stringnumber.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
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
#pragma hdrstop
#include "stringnumber.h"
#include <math.h>
#pragma package(smart_init)
 
strnum::strnum(){    //конструктор без параметров по умолчанию
    string="0";
    flag=false;
    return;
}
strnum::strnum(int Qs){                 //конструктор из целого числа
    if(Qs>=0){flag=false;}else{flag=true;}      // установка флага отрицательного числа
    string=IntToStr(abs(Qs));                   // запись модуля числа в строку
    return;
}
strnum::strnum(double Qs){              //конструктор из вещественного числа
    if(Qs>=0){flag=false;}else{flag=true;}      // установка флага отрицательного числа
    string=FloatToStr(fabs(Qs));                // запись модуля числа в строку
    return;
}
strnum::strnum(char* Qs){               //конструктор из строки
    flag=false;
    string=Qs;
        try{
        string.ToDouble();}
        catch(...){
        string="0";}
    if(string[1]=='-'){
    flag=true;string.Delete(1,1);}      // установка флага отрицательного числа
    return;
}
strnum::strnum(const strnum & Qs){          // конструктор копирования
        string=Qs.string;
    flag=Qs.flag;
        try{
        string.ToDouble();}
        catch(...){
        string="0";}
    return;
}
int strnum::dot(){                  // возвращает позицию точки с конца
    if((string.Pos('.')!=0))
    return string.Length()-string.Pos('.');
    else
    return 0;
}
 
 
strnum strnum::operator =(strnum Qs){ // присвоение
    string=Qs.string;
    flag=Qs.flag;
    return *this;
}
strnum strnum::operator =(int Qs){   // присвоение к целому (аналогично копированию)
    if(Qs>=0){flag=false;}else{flag=true;}
    string=IntToStr(abs(Qs));
    return *this;
}
strnum strnum::operator =(double Qs){   // присвоение к вещественному (аналогично копированию)
    if(Qs>=0){flag=false;}else{flag=true;}
    string=FloatToStr(fabs(Qs));
    return *this;
}
strnum strnum::operator =(char* Qs){ // присвоение к строке (аналогично копированию)
    flag=false;
    string=Qs;
        try{
        string.ToDouble();}
        catch(...){
        string="0";}
    if(string[1]=='-'){flag=true;string.Delete(1,1);}
    return *this;
}
strnum strnum::operator +(strnum &Qs){  // сложение
    strnum temp(*this);                 // вспомогательная переменная (результат)
    if((temp.flag)&&(!Qs.flag)) {       // -A+B
        temp.flag=false;
        return Qs-temp;                 // =>  B-A
    }
    if((!temp.flag)&&(Qs.flag)) {       // A+(-B)
        Qs.flag=false;
        return temp-Qs;                 // => B-A
    }
    if((temp.flag)&&(Qs.flag)) {        // -A+(-B)
        Qs.flag=false;
        temp.flag=false;
        return -(temp+Qs);              // =>  -(A+B)
    }
    int la,lb,a,b,n;                    // длина чисел, цифры, сумма цифр
    int dota,dotb,dotk;                 // позиция точек
    dota=temp.dot();
    dotb=Qs.dot();
    dotk=dota-dotb;                     // разность разрядов
    if(dota!=0)
    temp.string.Delete(temp.string.Pos('.'),1);  // удаление точек
    if(dotb!=0)
    Qs.string.Delete(Qs.string.Pos('.'),1);
    if(dotk<0){
    temp.addzerob(-dotk);               // дописывание сзади нулей
    }
    if(dotk>0){
    Qs.addzerob(dotk);                  // дописывание сзади нулей
    }
    la=temp.string.Length()+1;
    lb=Qs.string.Length()+1;            // добавляем спереди по одному нулю,
    temp.addzero(la);                   // на случай увеличения разряда
    Qs.addzero(lb);
    if (la>=lb){Qs.addzero(la);}else{temp.addzero(lb);la=lb;}  // выравниваем числа
    //if(Qs.string>temp.string){return Qs+temp;}  // если правое больше, то меняем местами
    for (int i = la; i!=0; i--) {  // начиная с первого разряда (с конца)
        a=temp.string[i]-48;       // выделяем цифру из символа (-48 - константа)
        b=Qs.string[i]-48;
        n=a+b;                     // складываем цифры
            if(n>=10){             // если больше 10, то
                n=n-10;                              // выносим единицы
                temp.string[i]=n+48;
                temp.string[i-1]=temp.string[i-1]+1; // а соседний разряд увеличиваем на 1
            }else{
                temp.string[i]=n+48;
            }
    }
    if(dotb>dota){                    // вставка точки на правильную позицию
     if(dotb!=0)temp.string.Insert('.',temp.string.Length()-dotb+1);
    }else{
    if(dotb<dota){
     if(dota!=0)temp.string.Insert('.',temp.string.Length()-dota+1);
    }else{
     if(dota!=0)temp.string.Insert('.',temp.string.Length()-dotk);
    }
    }
    temp.cutzero();      // вырезаем нули
    return temp;  // возвращаем ответ
}
strnum strnum::operator +(int Qs){  // сложение с числом
    strnum temp(*this);
    strnum temp2(Qs);               // создаем путем копирования
    return temp+temp2;              // вызываем стандартный оператор
}
strnum strnum::operator +(double Qs){  // сложение с числом
    strnum temp(*this);
    strnum temp2(Qs);               // создаем путем копирования
    return temp+temp2;              // вызываем стандартный оператор
}
strnum strnum::operator -(){        // отрицание (умножение на -1)
    flag=!flag;                     // просто меняем флаг
    return *this;
}
 
 
strnum strnum::operator -(strnum &Qs){   // вычитание
    strnum temp(*this),temp0(*this),temp2(Qs);                  // вспомогательная переменная (результат)
    if((temp.flag)&&(!Qs.flag)) {        // -A-B
        Qs.flag=false;
        temp.flag=false;
        return -(Qs+temp);               // => -(A+B)
    }
    if((!temp.flag)&&(Qs.flag)) {        // A-(-B)
        Qs.flag=false;
        return temp+Qs;                  // => A+B
    }
    if((temp.flag)&&(Qs.flag)) {         // -A-(-B)
        Qs.flag=false;
        temp.flag=false;
        return (Qs-temp);                // => B-A
    }
    int la,lb,a,b,n;
    int dota,dotb,dotk;                 // позиция точек
    dota=temp.dot();
    dotb=Qs.dot();
    dotk=dota-dotb;                     // разность разрядов
    if(dota!=0)
    temp.string.Delete(temp.string.Pos('.'),1);  // удаление точек
    if(dotb!=0)
    Qs.string.Delete(Qs.string.Pos('.'),1);
    if(dotk<0){
    temp.addzerob(-dotk);               // дописывание сзади нулей
    }
    if(dotk>0){
    Qs.addzerob(dotk);                  // дописывание сзади нулей
    }
    la=temp.string.Length()+1;
    lb=Qs.string.Length()+1;            // добавляем спереди по одному нулю,
    temp.addzero(la);                   // на случай увеличения разряда
    Qs.addzero(lb);
    if (la>=lb){Qs.addzero(la);}else{temp.addzero(lb);la=lb;}
        if(Qs.string>temp.string){            // если второе больше, то
        temp2.flag=false;
        temp0.flag=false;
        return -(temp2-temp0);                // -(B-A)
    }
    for (int i = la; i!=0; i--) {
        a=temp.string[i]-48;
        b=Qs.string[i]-48;
        n=a-b;
            if(n<0){                     // если надо занять в соседнем разряде
                n=n+10;
                temp.string[i]=n+48;
                temp.string[i-1]=temp.string[i-1]-1;  // вычитаем 10ку
            }else{
                temp.string[i]=n+48;
            }
    }
    if(dotb>dota){                    // вставка точки на правильную позицию
     if(dotb!=0)temp.string.Insert('.',temp.string.Length()-dotb+1);
    }else{
    if(dotb<dota){
     if(dota!=0)temp.string.Insert('.',temp.string.Length()-dota+1);
    }else{
     if(dota!=0)temp.string.Insert('.',temp.string.Length()-dotk);
    }
    }
    temp.cutzero();      // вырезаем нули
    return temp;         // возвращаем ответ
}
strnum strnum::operator -(int Qs){  // вычитание целого числа
    strnum temp(*this);
    strnum temp2(Qs);               // путем копирования
    return temp-temp2;              // возвращаем разность
}
strnum strnum::operator -(double Qs){  // вычитание вещественного числа
    strnum temp(*this);
    strnum temp2(Qs);               // путем копирования
    return temp-temp2;              // возвращаем разность
}
strnum strnum::operator *(int Qs){  // умножение на целое число
    strnum temp(*this);
    strnum temp2(Qs);               // путем копирования
    return temp*temp2;              // возвращаем произведение
}
strnum strnum::operator *(double Qs){  // умножение на вещественное число
    strnum temp(*this);
    strnum temp2(Qs);               // путем копирования
    return temp*temp2;              // возвращаем произведение
}
 
strnum strnum::operator *(strnum &Qs){ // умножение
    strnum temp;                       // промежуточное слагаемое
    strnum res;                        // конечный результат
    int la,lb;
    int dota,dotb,dotk;                 // позиция точек
    dota=dot();
    dotb=Qs.dot();
    dotk=dota+dotb;                     // сумма разрядов
    if(dota!=0)
    string.Delete(string.Pos('.'),1);  // удаление точек
    if(dotb!=0)
    Qs.string.Delete(Qs.string.Pos('.'),1);
    la= Qs.string.Length();
    lb= string.Length();
        if(string>Qs.string){return Qs**this;}
    for(int i=la;i>=1;i--){           // начиная с цифр первого числа
        for(int j=lb;j>=1;j--){       // умножаем на каждую цифру второго
            strnum k;                    // произведение двух цифр
            k=(string[j]-48)*(Qs.string[i]-48)*pow(10,lb-j); // pow - для правильного порядка
            temp=temp+k;              // складываем получившееся слагаемое
        }
       //   if(lb>la)la=lb;
        for(int ii=1;ii<=la-i;ii++)   // сдвигаем слагаемые как лесенку
        temp.string.Insert("0",temp.string.Length()+1); // путем добавления в конец нулей
        res=res+temp;                 // добавляем слагаемое к сумме
        temp=0;                       // обнуляем промежуточное
    }
    if(dotk!=0)
    res.string.Insert('.',res.string.Length()-dotk+1);
    if(flag==Qs.flag)                 // если одного знака, то
    return res;                       // возвращаем положительный результат
    else
    return -res;                     // иначе отрицательный
}
 
strnum strnum::falsedel (strnum &Qs){ // деление вычитаем
    strnum temp1(*this);
    strnum temp2(Qs);
    strnum res;
    temp1.flag=0;                     // убираем флаги
    temp2.flag=0;
    while (!temp1.flag){              // пока можем вычитать
    temp1=temp1-temp2;
    res=res+1;                        // увеличиваем результат на 1
    }
    if(temp1.flag)res=res-1;          // если вычли больше, то уменьшаем на 1
    return res;
}
 
strnum strnum::operator /(strnum &Qs){ // деление (столбиком)
    strnum temp,tmp;
    strnum r,lres,res;
    bool flag1=flag,flag2=Qs.flag;      // запоминаем знаки чисел
    int dota,dotb,dotk;                // позиция точек
    cutzero();                         // удаляем лишние нули
    Qs.cutzero();
        if(Qs.string=="0"){string="бесконечность =)";return *this;}
    dota=dot();                        // определяем позицию точек
    dotb=Qs.dot();
    if(dota!=0)
    string.Delete(string.Pos('.'),1);  // удаление точек
    if(dotb!=0)
    Qs.string.Delete(Qs.string.Pos('.'),1);
    addzerob(dotb+1);                 // дописывание сзади нулей
    Qs.addzerob(dota+1);
        *this=*this*100000000000000.;               // точность деления (6 знаков)
    r=0;                               // остаток от деления
    for(int i = 1; i <= string.Length(); ++i) {
        r = r*10;
        r= r + StrToInt(string[i]);         // сносим цифру
        lres = r.falsedel(Qs);              // находим цифру частного
        res.string=res.string+lres.string;  // записываем в результат
        tmp=lres*Qs ;                       // вычитаем в столбике
        r =r- tmp;                          // новый остаток
    }
 
    res.string.Insert(".",res.string.Length()-13);
    if(flag1==flag2)                 // если одного знака, то
    return res;                       // возвращаем положительный результат
    else
    return -res;                     // иначе отрицательный
}
strnum strnum::operator /(int Qs){ // деление на целое число (столбиком)
    strnum temp(Qs);
    return *this/temp;
}
strnum strnum::operator /(double Qs){ // деление на вещественное число (столбиком)
    strnum temp(Qs);
    return *this/temp;
}
strnum strnum::addzero(int k){       // добавление нулей спереди
    strnum temp(*this);
    while (temp.string.Length()<k)   // пока длина не станет k
        temp.string.Insert("0",1);   // приписываем спереди нолик
    string=temp.string;
    return *this;
}
strnum strnum::addzerob(int k){       // добавление нулей сзади
    strnum temp(*this);
    for(int i=0;i<k;i++)   
        temp.string.Insert("0",temp.string.Length()+1);   // приписываем сзади нолик
    string=temp.string;
    return *this;
}
strnum strnum::cutzero(){                    // удаление нулей
    while ((string!="")&&(string[1]=='0'))  // пока спереди есть нули
        string.Delete(1,1);                      // удаляем
    while ((string!="")&&(string[string.Length()]=='0')&&(string.Pos('.')!=0))  // пока спереди есть нули
        string.Delete(string.Length(),1);                      // удаляем
    if((string!="")&&(string[string.Length()]=='.'))string.Delete(string.Length(),1);
    if(string==""){string="0";}        // если ничего не осталось, то вернём 0
    return *this;
}
AnsiString strnum::astext(){                // вывод как текст
    cutzero();                         // уберём нули, если они есть
    if(flag){return ("-"+string);} // если отрицательное напишем минус
    return string;
}
программа для теста:
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
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "stringnumber.h" // наш класс
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
strnum q,w; // объявим две переменных нашего типа
 
void makenumbers() // проверка на правильный ввод
{
Form1->otvet->Caption="";
if (Form1->number_A->Text!=""){
try{ double d=StrToFloat(Form1->number_A->Text);
 q=Form1->number_A->Text.c_str();
}catch(EConvertError &){
Form1->otvet->Caption="В записи числа могут использоваться только 0-9, знак - и точка"; }}
else{Form1->otvet->Caption="Вы не ввели первое число";}
if(Form1->number_B->Text!=""){
try{ double d=StrToFloat(Form1->number_B->Text);
 w=Form1->number_B->Text.c_str();
}catch(EConvertError &){
Form1->otvet->Caption="В записи числа могут использоваться только 0-9, знак - и точка"; }}
else{Form1->otvet->Caption="Вы не ввели второе число";}
}
void __fastcall TForm1::btnPlusClick(TObject *Sender)
{makenumbers();
q=q+w;
if(otvet->Caption==””)otvet->Caption=q.astext() ;}
void __fastcall TForm1::btnMinusClick(TObject *Sender)
{makenumbers();
q=q-w;
if(otvet->Caption==””)otvet->Caption=q.astext() ;}
void __fastcall TForm1::btnMultiClick(TObject *Sender)
{makenumbers();
q=q*w;
if(otvet->Caption==””)otvet->Caption=q.astext() ;}
void __fastcall TForm1::btnDivClick(TObject *Sender)
{makenumbers();
q=q/w;
if(otvet->Caption==””)otvet->Caption=q.astext() ;}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.04.2010, 18:45
Ответы с готовыми решениями:

Программа на СИ. Поправить программу. Указатели, символьные строки и функции
:help: Здравствуйте! Необходима ваша помощь, я составил программу на языке СИ и нужно немного...

Прошу подсказать и поправить мой код для конвертации десятичного числа в другую систему счисления
Прошу подсказать и поправить мой код для конвертации десятичного числа в другую систему счисления...

Имеются класс А и вложенный в него класс В. Оба класса содержат символьные строки (private)
Сможет кто набросать 3 данные программы. Был бы благодарен))) 1. Имеются класс А и вложенный...

НУжно Поправить класс студент
Есть код программы но выбрасывает ошибки на всех компиляторах, скажите в чем проблема. заранее...

Поправить код
Для встречающихся в заданном тексте пар рядом расположенных символов указать, сколько раз...

2
12 / 12 / 1
Регистрация: 19.03.2010
Сообщений: 71
27.05.2010, 01:51 2
А если не секрет, что за программу ты делаешь ?
0
15 / 0 / 0
Регистрация: 29.11.2009
Сообщений: 26
27.05.2010, 15:40  [ТС] 3
программу, которая будет при вводе чаровской строки переводить ее в инт и производить основные действия над числами, курсач %)
я исправила, единственное деление не работает
0
27.05.2010, 15:40
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.05.2010, 15:40
Помогаю со студенческими работами здесь

Поправить код
Как сделать что б вы водило только 1 раз, если все правильно то &quot;Вы вошли в систему&quot;, а если нет,...

поправить код
помогите зделать так чтобы в этой матрице елементы матрици надо было вводить в ручную в паскале а...

Поправить код
Здравствуйте добрые люди! Помогите прошу, надо уже сдать курсовую, а я еще не сделал (работа и т.д,...

Поправить код
У меня есть готовый код, который писал не я. Там создается контейнер массив из чисел и строк. Но...

поправить код
Ребят,помогите поправить код.Всё работает, но неправильно немножко.В общем этот код проверяет папку...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru