определяемая пользователем строка::reserve()

#c

#c #c

Вопрос:

Итак, мы пишем набор определяемых пользователем функций, которые имитируют функции-члены класса string . Я застрял в резерве. Похоже, это должно сработать, но я чего-то не хватает. Я попробовал несколько разных вариантов, таких как размещение this-> перед переменными-членами или my string:: перед ними … мой вывод не меняется, но благодаря статусу cout, размещенному внутри функции, я знаю, что он обращается к функции.

вот код

 #include <cstdlib>
#include <iostream>
#include <string>
#include "mystring.h"
#define string mystring

using namespace std;


void check (string s, string name){
    cout << "checking " << name << endl;
    cout << name << " contains " << s << endl;
    cout << name << " capacity() is " << s.capacity() << endl;
    cout << name << " length() is " << s.length() << endl;
    cout << name << " size() is " << s.size() << endl;
    cout << name << " max_size() is " << s.max_size() << endl << endl;

}

int main(int argc, char** argv) {

    cout<<"This is Lab 5"<<endl;

    string s1("Hello, World!");//step 2
    string s1name("s1");//step 3

    check(s1,s1name);//step 4
    check(s1,s1name);//step 5

    cout << "---Testing assignment operator---nn";
{
string s2;
s2=s1;
string s2name("s2");
check(s2,s2name);
if(s1==s2)
    cout<<"comparison truen";
else 
    cout<<"comparison falsen";
}

    check(s1,s1name);



    string s3("check assignment");
    s3=s3;//checking to see if operator= is used when they are the same object. 

    check(s3,"s3");

    cout<<"Lab 5 ends"<<endl;//step6



//    //clear check
//    s3.clear();
//    check(s3,"s3");


//    if(s1==s3)
//        cout<<"comparison truen";
//    else
//        cout<<"comparison falsen";

// reserve check
//    mystring::size_type res;
//    res=40;

    s3.reserve(40);//still working on reserve
    check(s3,"s3");

    cout<<"in main buf size"<<s3.capacity()<<endl;

    s3.reserve(5);
    check(s3,"s3");



//    char* test=s3.begin();
//    cout<<amp;test<<endl;
//    cout<<amp;s3<<endl;


//empty check
//    string s4;
//    
//    if (s4.empty())
//        cout<<"Empty is truen";
//    else 
//        cout<<"Empty is falsen";







    return 0;
}





#ifndef MYSTRING_H
#define MYSTRING_H

#include <iostream>
#include <math.h>
#include <cstring>

using namespace std;

class mystring {
public:
    // types with scope in this class
    typedef unsigned int size_type;
    typedef char * iterator;
    typedef const char * const_iterator;
    static const long int npos = 1073741824;

    // default constructor
    mystring();//good
    // other constructors
    mystring(const char *);//good
    // copy constructor
    mystring(const mystringamp; orig);//

    // destructor
    ~mystring();////

    // iterators

    iterator begin();//good
    iterator end();//good

    //=== memory related ===

    // change buffer size to n
    void reserve(size_type n);

    size_type size() const;////good returns len
    size_type length() const;////good returns len
    size_type capacity() const;////good returns buf_size
    size_type max_size() const;////good
    bool empty() const;////good

    //=== overloading operators ===

     // assignment operator
    mystringamp; operator=(const mystringamp;);////
//    mystringamp; operator=(const char *);

    // array notation

    char operator[](size_type pos) const;
    charamp; operator[](size_type pos);

    // append

    mystringamp; operator =(const mystringamp; str);
    mystringamp; operator =(const char * str);

    //=== methods that modifiy the string

    void clear();////good

    void push_back(char c);


    mystringamp; append(const mystringamp; str);
    mystringamp; append(const char * str);

    mystringamp; insert(size_type pos, const mystringamp; str);
    mystringamp; insert(size_type pos, const char * str);

    mystringamp; replace(size_type start, size_type span, const mystringamp; str);
    mystringamp; replace(size_type start, size_type span, const char * str);

    //=== conversion to c string

    const char * c_str() const;//


private:
    // pointer to the memory location where string is stored as a c-style
    // string
    char * ptr_buffer;
    // the size of the memory in terms of bytes or characters capable of going into it currently
    size_type buf_size;
    // number of characters currently in the memory not including the
    // terminating null character
    size_type len;


};




#include "mystring.h"

// default constructor provided for lab 5
mystring::mystring() {
    ptr_buffer = new char[1];
    *ptr_buffer = '';
    buf_size = 1;
    len = 0;
}

// constructor from c-style string or "abc" provided for lab 5
mystring::mystring(const char * s) {
len = strlen(s);
buf_size = len   1;
ptr_buffer = new char[buf_size];
strcpy(ptr_buffer, s);

}

// copy constructor to be implemented in lab 5
mystring::mystring(const mystringamp; orig) {

    len=orig.length();
    ptr_buffer=new char[len 1];
    buf_size=len 1;

    for(int n=0 ;n<buf_size; n   )
    {
        ptr_buffer[n]=orig.ptr_buffer[n];
    }
    ptr_buffer[buf_size]='';
}



void mystring::reserve(size_type n)
{
    cout<<"cccccc:"<<capacity()<<endl;
    if( n > capacity() )
{
    const char* temp = ptr_buffer;
    ptr_buffer = new char[n];
    memcpy(ptr_buffer, temp, len 1);
    delete [] temp;
    buf_size=n;
    cout<<"bbbbbuf size"<<buf_size<<endl;
}



//    char *temp;
//    
//    temp=new char[n];
//    
//    int i=0;
//    
//    for(;i<=len;i  )
//    {
//        temp[i]=ptr_buffer[i];
//        
//    }
//    buf_size=n;
//    
//    delete [] ptr_buffer;
//    
//    ptr_buffer=temp;
//    

}







mystring::iterator mystring::begin()//think is working correctly
{
    iterator it=ptr_buffer;

    return it;
}

mystring::iterator mystring::end()//think is working correctly
{
    iterator it=ptr_buffer len;

    return it;
}



// one of the over loaded assignment operator to be implemented // assignment 3 (or for lab 5 if you have more time)
mystringamp; mystring::operator=(const mystringamp; orig){
    if(this!=amp;orig)
//    {
//        cout<<"this==amp;mystring  if statment activatedn";//comment out after testing
//        break;
//    }
    {
    delete this->ptr_buffer;

    this->len=orig.len;//length();
    this->ptr_buffer=new char((this->len) 1);
    this->buf_size=(this->buf_size) 1;
    cout<<"Using assignment operator="<<endl;
    for(int n=0;n<this->buf_size;n  )
    {
        this->ptr_buffer[n]=orig.ptr_buffer[n];
    }
    this->ptr_buffer[buf_size]='';
    return *this;

    }
}

// some simple methods provided for lab 5
 mystring::size_type mystring::size() const {
     return len;
 }
 mystring::size_type mystring::length() const{
     return len;
 }
 mystring::size_type mystring::capacity() const{
       return buf_size;
 }
 mystring::size_type mystring::max_size() const{
       return (int)pow(2,30) -4 ;
 }




 bool mystring::empty() const 
 {
     if(len==0)
         return true;
     else
         return false;
 }
// destructor to free space implemented for lab 5
mystring::~mystring() {
    delete [] ptr_buffer;
}
// provided for lab 5 so we may cout mystring
ostreamamp; operator<<(ostreamamp; out, const mystringamp; str) {
    out << str.c_str();
    return out;
}
// provided for lab 5 to support the implementation of <<
const char * mystring::c_str() const {
    return ptr_buffer;
}



char mystring::operator[](size_type pos) const
{
    return *(ptr_buffer pos);



}




void mystring::clear()
{
    char *temp;
    temp=new char[1];
    temp[0]='';

    ptr_buffer=temp;


    buf_size=0;
    len=0;
}




 void mystring::push_back(char c)
 {





 }







bool operator==(const mystringamp; lhs, const mystringamp; rhs)
{
   if(lhs.length()==rhs.length()) 
   {
       for(int i=0; i<lhs.length();i  )
       {
           if(lhs[i]!=rhs[i])
               return false;

       }
       return true;
   }

   return false;

}
  

Поэтому я вставил несколько операторов cout в reserve() функцию и в main . Резервные функции изменяют размер буфера, и вызов емкости возвращается правильно, но когда мы используем функцию проверки, она не показывает, что произошли какие-либо изменения. Я вставил пересмотренный код.

Хорошо, все. Оказывается, что функция проверки, объявленная перед main, создает копию mystring объекта. Конструктор копирования был определен для создания buf_size= len 1 . Так что я превратил его в buf_size=orig.buf_size . Вероятно, функция reserve работала так, как указано, и да, ей требовался параметр if, чтобы убедиться, что мы не сокращаем его, но я пока не беспокоился об этом. Я использовал пример daves с небольшим добавлением кода. спасибо всем за вашу помощь.

Комментарии:

1. В чем именно проблема? Способ reserve записи не должен изменять содержимое строки. Кстати: ваш reserve сбой завершится неудачей, если n < len . Редактировать: о, и завершающий символ «» отсутствует. Это может быть проблемой.

2. » копируется, потому что i<=len . Предполагается, что резерв завершится ошибкой, если он пытается уменьшить размер. я должен сравнивать с buffer_size, а не с link.

3. Перед публикацией кода на этом веб-сайте вам действительно следует удалить любой закомментированный код и любые строки функций, для которых вы говорите «это работает правильно». Просто сосредоточьтесь на проблеме, потому что мало у кого есть время просматривать сотни строк кода.

Ответ №1:

 void mystring::reserve(size_type n)
{
    if (n <= buf_size)
    {
        return;
    }
  

из MSDN basic_string::reserve Sets the capacity of the string to a number at least as great as a specified number.

So reserve не может использоваться для усечения строки

Здесь мы делаем что-то более сильное (мы не позволяем «пользователю» сокращать буфер). Ясно, что вы могли бы

     if (n <= len   1) // remember the  terminator is not included in len
    {
        return;
    }
  

и это было бы правильно.

Но даже первая форма была бы правильной. Нет никакой гарантии, что reserve это «уменьшит» размер буфера.

В общем, для копирования между буферами вы должны использовать memcpy длину len 1 . Это (обычно) быстрее (никто не требует, чтобы это было быстрее, но это быстрее :-))