Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
dimon1984
40 / 38 / 0
Регистрация: 22.01.2011
Сообщений: 670
#1

String1 - C++

28.02.2011, 15:55. Просмотров 795. Ответов 14
Метки нет (Все метки)

После долгих ковыряний задания из книги решил всётаки подсмотреть в ответы к упражнениям. Надо изменить класс String, наследовав его, чтобы при создании обьекта от производного класса String1 можно было предотвратить переполнение буфера при определении слишком большой строки.
Новый конструктор производного класса будет копировать в str только SZ-1 символов, если строка окажется слишком длинной, и будет копировать строку полностью, если она будет иметь длину меньшую, чем SZ.
Так дело в том, что попался такой ответ в книге, что тоже выдаёт ошибку:
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
#include <iostream>
#include <string>
using namespace std;
 
const int SZ=20;
/**/
class String         
{
  private:
    char str [ SZ ];  // массив для строки
  public:
    // конструктор без параметров
    String ( )
      { strcpy ( str, "" ); }
    // конструктор с одним параметром
    String ( char s [ ] )
      { strcpy ( str, s ); }
    // показ строки
    void display ( ) const
      { cout << str<<endl; }
    // оператор сложения
    String operator+ ( String ss ) const
      {
        String temp;  // временная переменная
        if ( strlen ( str ) + strlen ( ss.str ) < SZ )
        {
          strcpy ( temp.str, str );    // копируем содержимое первой строки
          strcat ( temp.str, ss.str ); // добавляем содержимое второй строки
        }
        else
        {
          cout << "\nПереполнение!";
          exit ( 1 );
        }
       return temp;  // возвращаем результат
      }
};
///////////////////////////////////////////////////////////
class String1: public String
{
private:
//  char st[SZ];         
public:
    String1 ( char s[ ] )
    {
        if(strlen(s)>SZ-1)        //проверка на переполнение
        {
            for(int i=0;i<SZ-1;i++)
                str[i]=s[i];
            str[i]='\0';
        }
        else String(s);          //по умолчанию
    }
//    void display ( ) const
//      { cout << st<<endl; }
};
 
///////////////////////////////////////////////////////////
int main ( )
{
    String1 s="hello world hello world hello world ";
    s.display();
 
 
    system("pause");
    return 0;
}
Как определить слишком длинную строку при создании обьекта?
Выдаёт ошибку в строке 49,50
for(int i=0;i<SZ-1;i++)
str[i]=s[i];
str[i]='\0';
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.02.2011, 15:55
Здравствуйте! Я подобрал для вас темы с ответами на вопрос String1 (C++):

char *strtor(string1,string2); - C++
Привет народ, реально вставить в strtor символ ограничитель &quot; ,если да то как ? Спасибо

Аварийное завершение программы (Прата, глава 12, string1) - C++
Доброго времени суток. Не могу понять, из-за чего происходит аварийное завершение программы. VS 2015 string1.h // string1.h --...

Написать функцию, которая возвращает указатель на первое вхождение подстроки string2 в строке string1 - C++
char* strstr(char* string1, char* string2) Возвращает указатель на первое вхождение подстроки string2 в строке string1. В случае неудачи...

InStr(string1, " ") - находит первый пробел. А последний пробел, чтобы быстро? - VBA
InStr(string1, &quot; &quot;) - находит первый пробел. Но ищет сначала строки. А как сконца? Посимвольно проверять ведь не интересно. Подкиньте,...

char *strtor(string1,string2); - C++
Привет народ, реально вставить в strtor символ ограничитель &quot; ,если да то как ? Спасибо

Аварийное завершение программы (Прата, глава 12, string1) - C++
Доброго времени суток. Не могу понять, из-за чего происходит аварийное завершение программы. VS 2015 string1.h // string1.h --...

Написать функцию, которая возвращает указатель на первое вхождение подстроки string2 в строке string1 - C++
char* strstr(char* string1, char* string2) Возвращает указатель на первое вхождение подстроки string2 в строке string1. В случае неудачи...

InStr(string1, " ") - находит первый пробел. А последний пробел, чтобы быстро? - VBA
InStr(string1, &quot; &quot;) - находит первый пробел. Но ищет сначала строки. А как сконца? Посимвольно проверять ведь не интересно. Подкиньте,...

char *strtor(string1,string2); - C++
Привет народ, реально вставить в strtor символ ограничитель &quot; ,если да то как ? Спасибо

Аварийное завершение программы (Прата, глава 12, string1) - C++
Доброго времени суток. Не могу понять, из-за чего происходит аварийное завершение программы. VS 2015 string1.h // string1.h --...

Написать функцию, которая возвращает указатель на первое вхождение подстроки string2 в строке string1 - C++
char* strstr(char* string1, char* string2) Возвращает указатель на первое вхождение подстроки string2 в строке string1. В случае неудачи...

InStr(string1, " ") - находит первый пробел. А последний пробел, чтобы быстро? - VBA
InStr(string1, &quot; &quot;) - находит первый пробел. Но ищет сначала строки. А как сконца? Посимвольно проверять ведь не интересно. Подкиньте,...

char *strtor(string1,string2); - C++
Привет народ, реально вставить в strtor символ ограничитель &quot; ,если да то как ? Спасибо

Аварийное завершение программы (Прата, глава 12, string1) - C++
Доброго времени суток. Не могу понять, из-за чего происходит аварийное завершение программы. VS 2015 string1.h // string1.h --...

Написать функцию, которая возвращает указатель на первое вхождение подстроки string2 в строке string1 - C++
char* strstr(char* string1, char* string2) Возвращает указатель на первое вхождение подстроки string2 в строке string1. В случае неудачи...

InStr(string1, " ") - находит первый пробел. А последний пробел, чтобы быс

char *strtor(string1,string2); - C++
Привет народ, реально вставить в strtor символ ограничитель &quot; ,если да то как ? Спасибо

Аварийное завершение программы (Прата, глава 12, string1) - C++
Доброго времени суток. Не могу понять, из-за чего происходит аварийное завершение программы. VS 2015 string1.h // string1.h --...

Написать функцию, которая возвращает указатель на первое вхождение подстроки string2 в строке string1 - C++
char* strstr(char* string1, char* string2) Возвращает указатель на первое вхождение подстроки string2 в строке string1. В случае неудачи...

InStr(string1, " ") - находит первый пробел. А последний пробел, чтобы быстро? - VBA
InStr(string1, &quot; &quot;) - находит первый пробел. Но ищет сначала строки. А как сконца? Посимвольно проверять ведь не интересно. Подкиньте,...


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

Или воспользуйтесь поиском по форуму:
14
Crudelis
Шаровик затейник
674 / 416 / 13
Регистрация: 06.05.2010
Сообщений: 1,109
28.02.2011, 16:10 #2
попробуйте измерить длину с помощью
C++
1
2
3
int len = strlen(s);
if(len>SZ)
cout<<"Stroka dlinnaya\n";
Добавлено через 1 минуту
Цитата Сообщение от dimon1984 Посмотреть сообщение
for(int i=0;i<SZ-1;i++)
str[i]=s[i];
str[i]='\0';
на счёт этого кода я вообще не пойму для чего здесь вот эта строка:
str[i]='\0';
как я понял это копирование строки, видно по циклу, как же она будет копироваться полностью, если на первой итерации коггда i будет равно 0 строка str сразу же обнулится...
0
dimon1984
40 / 38 / 0
Регистрация: 22.01.2011
Сообщений: 670
28.02.2011, 16:36  [ТС] #3
C++
1
2
3
4
5
6
                if(strlen(s)>SZ-1)        //проверка на переполнение
                {
                        for(int i=0;i<SZ-1;i++)
                                str[i]=s[i];
                        str[i]='\0';
                }
почему обнулится? ноль добавится после того, как полностью скопируется строка, потомучто цикл без скобок.
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
class String1: public String
{
private:
//  char st[SZ];
public:
    String1 ( char s[ ] )
    {
        int l=strlen(s);
        if(l>SZ)
        {
            cout<<"Stroka dlinnaya"<<endl;
        }
        else String(s);
    }
//    void display ( ) const
//      { cout << st<<endl; }
};
 
///////////////////////////////////////////////////////////
int main ( )
{
    String1 s="hello wo";
    s.display();
 
 
    system("pause");
    return 0;
}
теперь если длинная строка, то нормально выводит сообщение cout<<"Stroka dlinnaya, но s.display(); не показывает строку, даже если она не длинная.

Добавлено через 13 минут
вышеприведённая ошибка была такая:
str' : cannot access private member declared in class 'String'
0
Crudelis
Шаровик затейник
674 / 416 / 13
Регистрация: 06.05.2010
Сообщений: 1,109
28.02.2011, 17:09 #4
никуда ноль не добавиться, так как переменная i вышла из области своей видимости, и по этому в этой строке ошибка
C++
1
str[i]='\0';       //в этой строке i уже не существует
0
IrineK
Заблокирован
28.02.2011, 17:23 #5
В максимальном приближении к вашему коду, это работает:
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
#include <iostream>
#include <string>
#define SZ 20
using namespace std;
 
/**/
class String         
{
  protected:
    char str [ SZ ];  // массив для строки
  public:
    // конструктор без параметров
    String ( )
      { strcpy ( str, "" ); }
    // конструктор с одним параметром
    String ( char s [ ] )
      { strcpy ( str, s ); }
    // показ строки
    void display ( ) const
        {cout << str<<endl; }
    // оператор сложения
    String operator+ ( String ss ) const
      {
        String temp;  // временная переменная
        if ( strlen ( str ) + strlen ( ss.str ) < SZ )
        {
          strcpy ( temp.str, str );    // копируем содержимое первой строки
          strcat ( temp.str, ss.str ); // добавляем содержимое второй строки
        }
        else
        {
          cout << "\nПереполнение!";
          exit ( 1 );
        }
       return temp;  // возвращаем результат
      }
};
///////////////////////////////////////////////////////////
class String1: public String
{
public:
    String1 ( char s[ ] )
        {
            int i;
            char temp[ SZ ];
            if(strlen(s)>SZ-1)        //проверка на переполнение
                {
                        for(i=0;i<SZ-1;i++)
                                temp[i]=s[i];
                        temp[i]='\0';
                        strcpy (str,temp);
                    }
                else strcpy (str, s);          //по умолчанию
        }
};
 
/////////////////////////////////////////////////////////// 
int main ( )
{
       String1 s1="hello world hello world hello world";
       s1.display();
 
        system("pause");
        return 0;
}
0
dimon1984
40 / 38 / 0
Регистрация: 22.01.2011
Сообщений: 670
28.02.2011, 17:30  [ТС] #6
хорошо, убрал строку вообще str[i]='\0';
всёравно ошибка: str' : cannot access private member declared in class '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
class String1: public String
{
//private:
//  char st[SZ];
public:
    String1 ( char s[ ] )
    {
        char st[10];    //временная переменная
        int l=strlen(s);
        if(l>SZ-1)        //проверка на переполнение
        {
            for(int i=0;i<SZ-1;i++)
                   st[i]=s[i];
//                        str[i]='\0';
            String(st);   //передача врем-й переменной в конструктор
        }
        else String(s);
    }
 
};
 
int main ( )
{
    String1 s="hello";
    s.display();
 
    system("pause");
    return 0;
}
s.display(); не хочет показывать
0
IrineK
Заблокирован
28.02.2011, 17:34 #7
Да не убирайте ничего, загрузите мой код. Потом найдите 10 отличий.
0
dimon1984
40 / 38 / 0
Регистрация: 22.01.2011
Сообщений: 670
28.02.2011, 17:40  [ТС] #8
Да не убирайте ничего
сорри, это я не вам отвечал
пробовал IrineK как вы предложили, вылазит всё равно та ошибка
str' : cannot access private member declared in class 'String'
0
IrineK
Заблокирован
28.02.2011, 17:45 #9
Странно, у меня все работает. О_о
вы словечко protected видели?
1
dimon1984
40 / 38 / 0
Регистрация: 22.01.2011
Сообщений: 670
28.02.2011, 17:50  [ТС] #10
теперь увидел
в книге так же protected:
а всё таки, что по другому никак?
всё таки было задание добавить возможность а не изменять базовый класс
0
IrineK
Заблокирован
28.02.2011, 18:02 #11
Если по-другому, то:
Цитата Сообщение от dimon1984 Посмотреть сообщение
вылазит всё равно та ошибка
str' : cannot access private member declared in class 'String'
1
Crudelis
Шаровик затейник
674 / 416 / 13
Регистрация: 06.05.2010
Сообщений: 1,109
28.02.2011, 18:19 #12
я думаю вам стоит ещё раз тщательно почитать наследование и принципы доступа к элементам при наследовании. Если в базовом классе есть private члены и класс наследуется от него то доступ к таким членам будет закрыт в классе наследнике.
1
dimon1984
40 / 38 / 0
Регистрация: 22.01.2011
Сообщений: 670
28.02.2011, 18:32  [ТС] #13
я не спорю, что надо почитать. Но почему не выводит строку?
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
class String         
{
  protected:
    char str [ 10 ];  // массив для строки
  public:
    // конструктор без параметров
    String ( )
      { strcpy ( str, "" ); }
    // конструктор с одним параметром
    String ( char s [ ] )
      { strcpy ( str, s ); }
    // показ строки
    void display ( ) const
      { cout << str<<endl; }
    // оператор сложения
    String operator+ ( String ss ) const
      {
        String temp;  // временная переменная
        if ( strlen ( str ) + strlen ( ss.str ) < 10 )
        {
          strcpy ( temp.str, str );    // копируем содержимое первой строки
          strcat ( temp.str, ss.str ); // добавляем содержимое второй строки
        }
        else
        {
          cout << "\nПереполнение!";
          exit ( 1 );
        }
       return temp;  // возвращаем результат
      }
};
class String1: public String
{
public:
    String1 ( char s[ ] )
        {
                char st[10];    //временная переменная
                int l=strlen(s);
        if(l>SZ-1)        //проверка на переполнение
        {
            for(int i=0;i<SZ-1;i++)
                   st[i]=s[i];      //здесь нет обращения к закрытым данным
//                        str[i]='\0';
                   String(st);   //передача врем-й переменной в конструктор
        }
            else String(s);
        }
};
 
///////////////////////////////////////////////////////////
int main ( )
{
    String1 s="hello";
    s.display();
 
    system("pause");
    return 0;
}
s.display(); не выводит строку
0
IrineK
Заблокирован
28.02.2011, 18:44 #14
Потому что:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class String1: public String
{
public:
    String1 ( char s[ ] )
        {
                        int i;
                        char temp[ SZ ];
                        if(strlen(s)>SZ-1)        //проверка на переполнение
                {
                        for(i=0;i<SZ-1;i++)
                                temp[i]=s[i];
                        temp[i]='\0';
                   strcpy (str,temp);
                        }
                else strcpy (str, s);          //по умолчанию
        }
};
0
dimon1984
40 / 38 / 0
Регистрация: 22.01.2011
Сообщений: 670
28.02.2011, 18:53  [ТС] #15
пробовал IrineK как вы предложили, вылазит всё равно та ошибка
str' : cannot access private member declared in class 'String'
мне уже самому тошно, незнаю как вам
но ошибка какая-то назойливая попалась
1
28.02.2011, 18:53
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru