Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Есть пример из книжки, но он не работает  (Прочитано 14604 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Druid
Гость
« : 03-05-2006 15:15 » 

Есть пример из книжки Страуструпа, пытаюсь реализовать в Visual C++ выдает 46 ошибок, в BC++ 3.1 выдает 4 ошибки. Помогите пожалуйста. Вот код:

Код:
#include <iostream>
#include <cstring>


class string {
struct srep {
char* s;
int n; //счетчик числа ссылок
srep() {n = 1;}
};

srep* p;

public:
string(const char*);
srting();
string(const string &);
string& operator =(const char *);
string& operator =(const string &);
~string();
char & operator [](int i);
friend ostream& operator <<(ostream&, const string&);
friend istream& operator >>(istream&, string&);

friend int operator ==(const string & x, const char* s)
{ return 0 == strcmp(x.p->s,s); }

friend int operator ==(const string & x, const string & y)
{ return 0 == strcmp(x.p->s,y.p->s); }

friend int operator !=(const string & x, const char* s)
{ return 0 != strcmp(x.p->s,s); }

friend int operator !=(const string & x, const string & y)
{ return 0 != strcmp(x.p->s,y.p->s); }
};


string::srting()
{
p = new srep;
p->s = 0;
}

string::srting(const string& x)
{
x.p = n++;
p = x.p;
}

string::srting(const char* s)
{
p = new srep;
p->s = new char[strlen(s) + 1];
strcpy(p->s,s);
}

string::~string()
{
if (0 == --p->n) {
delete[] p->s;
delete p;
}
}

string& string::operator =(const char* s)
{
if (p->n > 1) { // отсоединяемся от старой строки
p->n--;
p = new srep;
}
else // освобождаем строку со старым значением
delete p->s;

p->s = new char[strlen(s) + 1];
strcpy(p->s,s);
return *this;
}

string& string::operator =(const string& x)
{
x.p->n++; // защита от случая "st = st"
if (0 == --p->n) {
delete[] p->s;
delete p;
}

p = x.p;
return *this;
}

ostream& operator <<(ostream& s, const string& x)
{
return s << x.p->s << "[" << x.p->n << "]\n";
}

istream& operator >>(istream& s, string& x)
{
char buf[256];
s >> buf; // ненадежно, возможно переполнение buf
  // см. 10,3
x = buf;
cout << "echo: " << x << "\n";
return s;
}

void error(const char* p)
{
cerr << p << "\n";
exit(1);
}

char& string::operator [](int i)
{
if (i<0 || strlen(p->s)<i) error("недопустимое значение индекса");
return p->s[i];
}


int main()
{
string x[100];
int n;

cout << "здесь начало\n";

for(n=0; cin>>x[n]; n++) {
if (100 == n) {
error("слишком много слов");
return 99;
}

string y;
cout << (y = x[n]);
if (y == "doun") break;
}

cout << "теперь мы идем по словам в обратном порядке \n";
for(int i=n-1; 0<=i; i--) cout << x[i];
return 0;
}
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 03-05-2006 15:36 » 

Druid, сами ошибки то же приведи.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #2 : 03-05-2006 16:41 » 

Места, где я вижу явные ошибки
Код:
string::srting(const string& x)
{
x.p = n++;    // <--- Тут явная ошибка. Опечатка. Скорее всего за место знака = надо ставить ->
p = x.p;
}
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 03-05-2006 16:59 » 

косяки:
1)

string::srting(const string& x)
{
   x.p = n++;   p = x.p;
}

- очепятка + неопределена n

дальше - не знаю, всякое может быть
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #4 : 03-05-2006 17:21 » 

Алексей1153, Я даже не заметил опечатки.
Тогда есть еше одна опечатка
string::srting(const char* s)       //Надо писать string, а не srting.
{
   p = new srep;
   p->s = new char[strlen(s) + 1];
   strcpy(p->s,s);
}

Кстати и в определении конструктора по дефаулту, обратно этот srting.
« Последнее редактирование: 03-05-2006 17:29 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 03-05-2006 18:03 » 

Finch, а это не я, это компилятор заметил

и ещё он ругается на строки
friend ostream& operator <<(ostream&, const string&);
friend istream& operator >>(istream&, string&);
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #6 : 03-05-2006 18:21 » 

У меня это решилось просто. я за место #include <iostream> поставил #include <iostream.h>.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Druid
Гость
« Ответ #7 : 03-05-2006 19:55 » 

Алексей1153, Я даже не заметил опечатки.
Тогда есть еше одна опечатка
string::srting(const char* s)       //Надо писать string, а не srting.
{
   p = new srep;
   p->s = new char[strlen(s) + 1];
   strcpy(p->s,s);
}

Кстати и в определении конструктора по дефаулту, обратно этот srting.

Упс, это невнимательность, я даже не подумал что мог просто слово не так написать ((

Поправил все ошибки, подключил <iostream.h> вместо <iostream>. Под компилятором BC++ 3.1 все заработало вообще на ура, под Visual C++ выдает предупреждение "warning C4018: '<' : signed/unsigned mismatch" - "несоответствие знаков в операции '<' ".

Такой вопрос, почему при замене <iostream.h> на <iostream> появляется 42 ошибки. Ведь насколько я понял <iostream> это стандартизированная версия той же <iostream.h>, да еще с большими возможностями. Почему же такое несоответствие может быть?
« Последнее редактирование: 19-12-2007 18:19 от Алексей1153++ » Записан
Druid
Гость
« Ответ #8 : 03-05-2006 20:03 » 

Вспомнил по новому стандарту есть пространство имен std.
Прописал:
using namespace std;
Ошибки сократились с 42 до 12 Улыбаюсь
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #9 : 03-05-2006 20:09 » 

"warning C4018: '<' : signed/unsigned mismatch"  это предупреждение говорит о том, что у тебя идет сравнение знаковой переменной с не знаковой. Могут быть проблемы в данном месте. Просто VC в этом отношении отличается от Борландовских компиляторов. Чуть другой подход. И из-за этого я ловил несколько раз глюки, когда переносил проект. И значения переменных были на границах значимости.
« Последнее редактирование: 19-12-2007 18:22 от Алексей1153++ » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Druid
Гость
« Ответ #10 : 03-05-2006 20:18 » 

"warning C4018: '<' : signed/unsigned mismatch"  это предупреждение говорит о том, что у тебя идет сравнение знаковой переменной с не знаковой. Могут быть проблемы в данном месте. Просто VC в этом отношении отличается от Борландовских компиляторов. Чуть другой подход. И из-за этого я ловил несколько раз глюки, когда переносил проект. И значения переменных были на границах значимости.

Интересно. Спасибо.
Кстати оставшиеся 12 ошибок говорят о "ambiguous" двойной значимости практически везде где переопределил операции.
не удобно пихать в сообщение большой этот код, ну да не знаю как его прицепить иначе, вот как стала выглядеть программа:
Код:
#include <iostream>
#include <string.h>
#include <stdlib.h>

using namespace std;

class string {
struct srep {
char* s;
int n; //счетчик числа ссылок
srep() {n = 1;}
};

srep* p; //!!!Ругается - говорит что здесь что-то не так...

public:
string(const char*);
string();
string(const string &);
string& operator =(const char *);
string& operator =(const string &);
~string();
char & operator [](int i);
friend ostream& operator <<(ostream&, const string&);
friend istream& operator >>(istream&, string&);

friend int operator ==(const string & x, const char* s)
{ return 0 == strcmp(x.p->s,s); }

friend int operator ==(const string & x, const string & y)
{ return 0 == strcmp(x.p->s,y.p->s); }

friend int operator !=(const string & x, const char* s)
{ return 0 != strcmp(x.p->s,s); }

friend int operator !=(const string & x, const string & y)
{ return 0 != strcmp(x.p->s,y.p->s); }
};


string::string()
{
p = new srep;
p->s = 0;
}

string::string(const string& x)
{
x.p->n++;
p = x.p;
}

string::string(const char* s)
{
p = new srep;
p->s = new char[strlen(s) + 1];
strcpy(p->s,s);
}

string::~string()
{
if (0 == --p->n) {
delete[] p->s;
delete p;
}
}

string& string::operator =(const char* s)
{
if (p->n > 1) { // отсоединяемся от старой строки
p->n--;
p = new srep;
}
else // освобождаем строку со старым значением
delete p->s;

p->s = new char[strlen(s) + 1];
strcpy(p->s,s);
return *this;
}

string& string::operator =(const string& x)
{
x.p->n++; // защита от случая "st = st"
if (0 == --p->n) {
delete[] p->s;
delete p;
}

p = x.p;
return *this;
}

ostream& operator <<(ostream& s, const string& x)
{
return s << x.p->s << "[" << x.p->n << "]\n";
}

istream& operator >>(istream& s, string& x)
{
char buf[256];
s >> buf; // ненадежно, возможно переполнение buf
  // см. 10,3
x = buf;
cout << "echo: " << x << "\n";
return s;
}

void error(const char* p)
{
cerr << p << "\n";
exit(1);
}

char& string::operator [](int i)
{
if (i<0 || strlen(p->s)<i) error("недопустимое значение индекса");
return p->s[i];
}


int main()
{
string x[100];
int n;

cout << "здесь начало\n";

for(n=0; cin>>x[n]; n++) {
if (100 == n) {
error("слишком много слов");
return 99;
}

string y;
cout << (y = x[n]);
if (y == "doun") break;
}

cout << "теперь мы идем по словам в обратном порядке \n";
for(int i=n-1; 0<=i; i--) cout << x[i];
return 0;
}

« Последнее редактирование: 19-12-2007 18:23 от Алексей1153++ » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #11 : 03-05-2006 20:33 » 

Вот твой пример, который у меня компилится без ворнинга и ошибок
Код:
#include <iostream.h>
#include <string.h>
//#include <stdlib.h>

//using namespace std;

class string {
struct srep {
char* s;
int n; //счетчик числа ссылок
srep() {n = 1;}
};

srep* p; //!!!Ругается - говорит что здесь что-то не так...

public:
string(const char*);
string();
string(const string &);
string& operator =(const char *);
string& operator =(const string &);
~string();
char & operator [](int i);
friend ostream& operator <<(ostream&, const string&);
friend istream& operator >>(istream&, string&);

friend int operator ==(const string & x, const char* s)
{ return 0 == strcmp(x.p->s,s); }

friend int operator ==(const string & x, const string & y)
{ return 0 == strcmp(x.p->s,y.p->s); }

friend int operator !=(const string & x, const char* s)
{ return 0 != strcmp(x.p->s,s); }

friend int operator !=(const string & x, const string & y)
{ return 0 != strcmp(x.p->s,y.p->s); }
};


string::string()
{
p = new srep;
p->s = 0;
}

string::string(const string& x)
{
x.p->n++;
p = x.p;
}

string::string(const char* s)
{
p = new srep;
p->s = new char[strlen(s) + 1];
strcpy(p->s,s);
}

string::~string()
{
if (0 == --p->n) {
delete[] p->s;
delete p;
}
}

string& string::operator =(const char* s)
{
if (p->n > 1) { // отсоединяемся от старой строки
p->n--;
p = new srep;
}
else // освобождаем строку со старым значением
delete p->s;

p->s = new char[strlen(s) + 1];
strcpy(p->s,s);
return *this;
}

string& string::operator =(const string& x)
{
x.p->n++; // защита от случая "st = st"
if (0 == --p->n) {
delete[] p->s;
delete p;
}

p = x.p;
return *this;
}

ostream& operator <<(ostream& s, const string& x)
{
return s << x.p->s << "[" << x.p->n << "]\n";
}

istream& operator >>(istream& s, string& x)
{
char buf[256];
s >> buf; // ненадежно, возможно переполнение buf
  // см. 10,3
x = buf;
cout << "echo: " << x << "\n";
return s;
}

void error(const char* p)
{
cerr << p << "\n";
//exit(1);
}

char& string::operator [](int i)
{
if ((i<0) || ((int)strlen(p->s)<i)) error("недопустимое значение индекса");
return p->s[i];
}


int main()
{
string x[100];
int n;

cout << "здесь начало\n";

for(n=0; cin>>x[n]; n++) {
if (100 == n) {
error("слишком много слов");
return 99;
}

string y;
cout << (y = x[n]);
if (y == "doun") break;
}

cout << "теперь мы идем по словам в обратном порядке \n";
for(int i=n-1; 0<=i; i--) cout << x[i];
return 0;
}
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #12 : 03-05-2006 20:37 » new

Кстати класс называть string это ходить по минному полю. Уже до тебя использовали такое название в стандартных библиотеках. 
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines