Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> friend std::istream &operator>> для класса строки, реализация 
V
    Опции темы
anatox91
Дата 16.5.2008, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


программист-самоучка
**


Профиль
Группа: Участник
Сообщений: 699
Регистрация: 12.1.2008
Где: ++Украина.Крым++

Репутация: 1
Всего: 13



подскажите пожалуйста как реализовать сабж. с operator<< собсно все легко, а вот этот оператор как-то не доганяю как реализовать
приват-секция моего класса:
Код

char *string;
unsigned int len;

пишу 
Код

friend std::istream &operator>>(std::istream& in, cstring &obj) {
              //...
              return in;
              }

а дальше че-то не доганяю, подскажите пожалуйста
заранее большое спасибо! с меня +  smile 

Это сообщение отредактировал(а) anatox91 - 16.5.2008, 13:31


--------------------

The code is the design ©

Sony VAIO VGN-FW480J

user posted image
PM MAIL ICQ   Вверх
baldina
Дата 16.5.2008, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



ну во первых cstring &obj не const - туда же записывается.

проще всего - через std::string

Код

friend std::istream &operator>>(std::istream& in, cstring &obj) {
              std::string s;
              in >> s;
              obj.len = s.size ();
              obj.string = new char[obj.len+1];
              strcpy (obj.string, s.c_str ());
              return in;
              }


Это сообщение отредактировал(а) baldina - 16.5.2008, 13:23
PM MAIL   Вверх
anatox91
Дата 16.5.2008, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


программист-самоучка
**


Профиль
Группа: Участник
Сообщений: 699
Регистрация: 12.1.2008
Где: ++Украина.Крым++

Репутация: 1
Всего: 13



про конст забыл  smile 
через std::string я то знаю что можно сделать, интересно можно ли это сделать без классов типа std::string, CString


--------------------

The code is the design ©

Sony VAIO VGN-FW480J

user posted image
PM MAIL ICQ   Вверх
baldina
Дата 16.5.2008, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



можно. вызывай в цикле in.getline () с временным буфером, перераспределяй память и копируй в свой char*
PM MAIL   Вверх
anatox91
Дата 16.5.2008, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


программист-самоучка
**


Профиль
Группа: Участник
Сообщений: 699
Регистрация: 12.1.2008
Где: ++Украина.Крым++

Репутация: 1
Всего: 13



ясно, попробую


--------------------

The code is the design ©

Sony VAIO VGN-FW480J

user posted image
PM MAIL ICQ   Вверх
anatox91
Дата 16.5.2008, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


программист-самоучка
**


Профиль
Группа: Участник
Сообщений: 699
Регистрация: 12.1.2008
Где: ++Украина.Крым++

Репутация: 1
Всего: 13



короче решил для начала написать функцию , которая добавляла бы в конец строки другую строку, чтобы меньше было возни с перераспределением памяти, вроде работает нормально, но почему-то всегда в конец добавляет символ пробела smile
вот код:
Код

cstring &append(const char *str) {
               if(!len) {
                        len = strlength(str); //my function for count string length
                        string = new char[len + 1];
                        unsigned int i=0;
                        for(; i < len; i++) {
                              string[i] = str[i];
                              }
                        string[i] = '\0';
                        }
               else {
                    unsigned int buf_len = len;
                    char *buf = new char[buf_len]; //creating buffer for copy string
                    unsigned int k=0; //iterator
                    for(; k < buf_len; k++) buf[k] = string[k]; //copying string to buffer
                    
                    delete[] string; //deleting old string
                    len += strlength(str); //my function for count string length
                    string = new char[len + 1]; 
                    for(k=0; k < buf_len; k++) { //copying characters from buffer
                             string[k] = buf[k];
                             }
                    delete[] buf; //clearing buffer
                    unsigned int c=0;
                    for(; k < len; k++, c++) { //copying characters from added string
                          string[k] = str[c];
                          }
                    string[k] = '\0'; //add null
                    return *this; //return new object
                    }
               }
  
и еще. 
baldina, я только не понимаю, какое тогда условие задать для цикла?

Это сообщение отредактировал(а) anatox91 - 16.5.2008, 20:26


--------------------

The code is the design ©

Sony VAIO VGN-FW480J

user posted image
PM MAIL ICQ   Вверх
bsa
Дата 16.5.2008, 21:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



anatox91, а зачем ты лишний раз память выделял и освобождал? Кто тебе мешал сразу под buf выделить память, необходимую для хранения результирующей строки (строка 13). Тогда бы тебе не нужно было делать строки 19-23
PM   Вверх
anatox91
Дата 16.5.2008, 22:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


программист-самоучка
**


Профиль
Группа: Участник
Сообщений: 699
Регистрация: 12.1.2008
Где: ++Украина.Крым++

Репутация: 1
Всего: 13



bsa, ты имел ввиду что-то типа такого ?
Код

else {
         len += strlength(str);
         char *buf = new char[len+1];
         unsigned int k=0; 
         for(; string[k]; k++) buf[k] = string[k];
                    
         unsigned int c=0;
         for(; k < len; k++, c++) { 
                     buf[k] = str[c];
                          }
         buf[k] = '\0';
         delete[] string;
         string = buf;
         return *this; 
           }



Это сообщение отредактировал(а) anatox91 - 16.5.2008, 22:08


--------------------

The code is the design ©

Sony VAIO VGN-FW480J

user posted image
PM MAIL ICQ   Вверх
bsa
Дата 16.5.2008, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



anatox91, да.
PM   Вверх
anatox91
Дата 16.5.2008, 22:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


программист-самоучка
**


Профиль
Группа: Участник
Сообщений: 699
Регистрация: 12.1.2008
Где: ++Украина.Крым++

Репутация: 1
Всего: 13



а можно поподробнее насчет цикла smile 
Цитата(baldina @  16.5.2008,  13:40 Найти цитируемый пост)
вызывай в цикле in.getline () с временным буфером, перераспределяй память и копируй в свой char*

и какое условие ставить я чет не пойму... 





--------------------

The code is the design ©

Sony VAIO VGN-FW480J

user posted image
PM MAIL ICQ   Вверх
bsa
Дата 16.5.2008, 23:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



anatox91, getline() читает строку до тех пор, пока не будет достигнут конец строки, конец файла, либо не заполнится предоставленный буфер.
PM   Вверх
opjox
Дата 17.5.2008, 21:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 90
Регистрация: 17.1.2008

Репутация: 2
Всего: 14



Код

#include <iostream>

class cstring {
public:
  cstring() 
  {
    len=0; 
    buf=0;
  }

  friend std::istream& operator>>(std::istream &in, cstring &obj)
  {
    std::istream::sentry s(in);       // ждем, пока в буфере будет хотя бы что-то
    if(s) {
      std::streambuf *p = in.rdbuf(); // получаем указатель на буфер с данными
      obj.len = p->in_avail();        // получаем, сколько сейчас можно считать из буфера
      
      if(obj.buf) delete [] obj.buf;
      obj.buf = new char[obj.len];

      for(size_t i=0; i<obj.len; i++) obj.buf[i] = p->sbumpc(); // копируем в наш буфер
      obj.buf[obj.len] = 0;
    }
    return in;
  }

  friend std::ostream& operator<<(std::ostream &out, const cstring &obj)
  {
    out << obj.buf;
    return out;
  }

private:
  char * buf;
  size_t len;
};

int main()
{
  cstring a;
  std::cin >> a;
  std::cout << a;
  return 0;
}


[+] выделение памяти и копирование происходит только один раз
[-]  данная реализация не обращает внимания на символы-разделители, читает все скопом в память

PM MAIL ICQ   Вверх
opjox
Дата 17.5.2008, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 90
Регистрация: 17.1.2008

Репутация: 2
Всего: 14



Цитата(opjox @  17.5.2008,  21:25 Найти цитируемый пост)
[-]  данная реализация не обращает внимания на символы-разделители, читает все скопом в память

пофиксил:

Код

class cstring {
public:
  cstring(): separators(" \n\t")
  {
    len=0; 
    buf=0;
  }

  friend std::istream& operator>>(std::istream &in, cstring &obj)
  {
    std::istream::sentry s(in);       // ждем, пока в буфере будет хотя бы что-то
    if(s) {
      std::streambuf *p = in.rdbuf(); // получаем указатель на буфер с данными
      size_t len = p->in_avail();        // получаем, сколько сейчас можно считать из буфера
      
      // узнаем, сколько символов до разделителя
      //
      obj.len = 0;                 
      while(len && obj.it_not_separator(p->sbumpc())) {
        len--;
        obj.len++;
      }
      // узнали, сколько символов до разделителя

      for(len=0; len<=obj.len; len++) p->sungetc(); // теперь вернемся к первому символу
      
      if(obj.buf) delete [] obj.buf;
      obj.buf = new char[obj.len+1];

      for(size_t i=0; i<obj.len; i++) obj.buf[i] = p->sbumpc(); // копируем в наш буфер
      obj.buf[obj.len] = 0;
    }
    return in;
  }

  friend std::ostream& operator<<(std::ostream &out, const cstring &obj)
  {
    out << obj.buf;
    return out;
  }

private:
  bool it_not_separator(char c)
  {
    const char *p = separators;
    for(;*p;p++) if(*p==c) return false;
    return true;
  }

  const char *separators; // все возможные символы-разделители

  char *buf;
  size_t len;
};

PM MAIL ICQ   Вверх
anatox91
Дата 18.5.2008, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


программист-самоучка
**


Профиль
Группа: Участник
Сообщений: 699
Регистрация: 12.1.2008
Где: ++Украина.Крым++

Репутация: 1
Всего: 13



чет не работает  smile 
после ввода строки сразу закрывается прога:
Код

cstring s;
std::cin >> s;
std::cout << s;
std::cin.get();

и если так, то тоже не выводит ничего после ввода:
Код

cstring first("example:");
cstring second;
std::cout << first;
std::cin >> second;
std::cout << second;
system("pause");


Код

friend std::istream &operator>>(std::istream& in, cstring &obj) {
              std::istream::sentry s(in);
              if(s) {
                    std::streambuf *p = in.rdbuf();
                    size_t len = p->in_avail();
                    
                    obj.len = 0;
                    while(len && obj.it_not_separator(p->sbumpc())) {
                              len--;
                              obj.len++;
                              }
                    for(len = 0; len <= obj.len; len++) p->sungetc();
                    
                    if(obj.string) delete[] obj.string;
                    obj.string = new char[obj.len + 1];
                    
                    for(size_t i = 0; i < obj.len; i++) obj.string[i] = p->sbumpc();
                    obj.string[obj.len] = '\0';
                    }
              return in;
              }

кстати а разве катит простой ноль в конце:
Цитата

Код

obj.string[obj.len] = 0;


вместо этого
Код

obj.string[obj.len] = '\0';

?

Это сообщение отредактировал(а) anatox91 - 18.5.2008, 10:39


--------------------

The code is the design ©

Sony VAIO VGN-FW480J

user posted image
PM MAIL ICQ   Вверх
bsa
Дата 18.5.2008, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(anatox91 @ 18.5.2008,  10:38)
кстати а разве катит простой ноль в конце:
Цитата

Код

obj.string[obj.len] = 0;


вместо этого
Код

obj.string[obj.len] = '\0';

?

катит.
Но лучше типизировать (т.е. использовать '\0'), имхо.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1388 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.