Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
36 / 36 / 27
Регистрация: 05.11.2013
Сообщений: 149
1

Не работает strcat в QtCreator

14.04.2014, 22:50. Просмотров 1697. Ответов 23
Метки нет (Все метки)

Всем привет. Написал класс для работы со строками в Визуал студио(в ней перегруженный оператор + конкатенирует строки) в QtCreator оператор + нивкакую не хочет перегружаться, а точнее не объединяет строки, а просто выводит на екран неизмененную строку. Кто нибудь может подсказать что с ним сделать в Qt?
Вот код перегрузки
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
String String::operator+(const String &s)
{
    String temp;
    temp.len = len +s.len;
    temp.str = new char[temp.len+1];
    strcpy(temp.str,str);
    strcat(temp.str,s.str);
    return temp;
}
 
String String::operator+(const char *s)
{
    String temp;
    temp.len=len+strlen(s);
    temp.str = new char[temp.len+1];
    strcpy(temp.str,str);
    strcat(temp.str,s);
    return temp;
}
Добавлено через 4 минуты
И еще вопрос не по теме. Я гдето читал что ф-ции библиотеки cstring не будут поддерживаться стандарту. Это правда или нет?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.04.2014, 22:50
Ответы с готовыми решениями:

Не работает strcat
Вот простая программа. #include "stdafx.h" #include <stdio.h> #include <string.h> int...

Не работает функция strcat
По каким то причинам не работает функция strcat strcat(PatchToFile, FILE_READ_ACCESS,...

Неправильно работает strcat
Всем привет! Прошу помощи у знающих, сам никак не могу справиться... Имеется код: char* editor...

не работает strcat, отладчик выбрасывает окно с ошибкой
MV Studio Express 2012,windows 7 64, Необработанное исключение по адресу 0x000000013F2B1099 в...

23
Заблокирован
14.04.2014, 23:53 2
Пробуем так:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
String &String::operator+(const String &s)
{
    String temp;
    temp.len = len +s.len;
    temp.str = new char[temp.len+1];
    strcpy(temp.str,str);
    strcat(temp.str,s.str);
    return temp;
}
 
String &String::operator+(const char *s)
{
    String temp;
    temp.len=len+strlen(s);
    temp.str = new char[temp.len+1];
    strcpy(temp.str,str);
    strcat(temp.str,s);
    return temp;
}


А вообще тут как-то нехорошо с памятью.
2
36 / 36 / 27
Регистрация: 05.11.2013
Сообщений: 149
15.04.2014, 00:22  [ТС] 3
Спасибо я уже понял в чем проблема. Я забывал присваивать значение двух строк третьему объекту. Ваш вариант тоже реализовал)).
Нащет памяти, то конструктор по умолчанию у меня выглядит так:
C++ (Qt)
1
2
3
4
5
String::String()
{
    len = 0;
    str = NULL;
}
Поидее бессмыслено удалять нулевой указатель)
0
Заблокирован
15.04.2014, 11:38 4
У вас идет утечка памяти. Нужно убить старую строку str - она же непустая.
0
13712 / 7335 / 1751
Регистрация: 30.01.2014
Сообщений: 12,307
15.04.2014, 11:52 5
Цитата Сообщение от IrineK Посмотреть сообщение
Пробуем так:
Вообще-то это UB. Ссылка на локальный объект.

Добавлено через 8 минут
Цитата Сообщение от Hrollo Посмотреть сообщение
Я гдето читал что ф-ции библиотеки cstring не будут поддерживаться стандарту.
Нет, не правда. Если бы кто-то предложил такое, его бы сразу сочли сумасшедшим. Ибо это означало бы, что миллионы строк кода в новом компиляторе перестали бы собираться. Это совершенно не в духе С++, отказываться от обратной совместимости. Даже безполезные нынче триграфы убрали из стандарта только совсем недавно, хотя не применяются они наверное уже около двух десятков лет.
0
:)
Эксперт С++
4763 / 3257 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
15.04.2014, 13:15 6
DrOffset, когда это успели триграфы убрать из стандарта? В C++11 есть, а 14 еще не утвердили.
1
13712 / 7335 / 1751
Регистрация: 30.01.2014
Сообщений: 12,307
15.04.2014, 13:41 7
Цитата Сообщение от Tulosba Посмотреть сообщение
DrOffset, когда это успели триграфы убрать из стандарта? В C++11 есть, а 14 еще не утвердили.
И то правда. Перепутал с другой вещью:
Убрали ее в GCC из списка поддерживаемых фич по умолчанию, теперь нужно специально их включать опцией -trigraphs.
Hrollo, видишь, даже триграфы не убрали, так что про cstring - это вообще нонсенс
0
Заблокирован
15.04.2014, 13:53 8
Hrollo,
у вас temp делает не то, что нужно.


Кликните здесь для просмотра всего текста
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
#include <iostream>
 
class String
{
public:
    String (): len(0), str(NULL) {}
    String ( char *_str, int _len) : len (_len)
    {   str = new char [len + 1];
        strncpy (str, _str, _len+1);
    }
 
    String (const String &s) : len (s.len)
    {   str = new char [len + 1];
        strncpy (str, s.str, s.len+1);
    }
 
    ~String ()
    {   delete [] str;
    }
 
 
    String &operator = (const String &s)
    {   if (str == s.str && len == s.len) 
        return *this;
     
        if (str != NULL)
        {   delete [] str;
            str = NULL;
        }
        len = s.len;
        str = new char [len + 1];
        strncpy (str, s.str, s.len+1);
        return *this;
    }
 
    String &operator += (const String &s);
    String &operator += (const char *s);
 
    friend std::ostream &operator <<(std::ostream & os, const String &s);
 
private:
    int len;
    char *str;
};
 
String &String :: operator += (const String &s)
{   String temp (*this);
    
    if (str != NULL)
    {   delete [] str;
        str = NULL;
    }
 
    len = temp.len + s.len;
    str = new char [len + 1];
    strncpy (str, temp.str, temp.len+1);
    strncat (str, s.str, s.len+1);
    return *this;
}
 
std::ostream &operator <<(std::ostream & os, const String &s)
{   os << s.str;
    return os;
}
 
 
int main()
{   String s1 ("12345", 5);
    String s2 ("999", 3);
    std :: cout << s1 << " " << s2 << '\n';
    s1 += s2;
    std :: cout << s1 << '\n';
 
    s2 = s1;
    std :: cout << s2 << '\n';
 
    s2 += s1;
    std :: cout << s2 << '\n';
 
    std::cin.get();
    return 0;
}
0
13712 / 7335 / 1751
Регистрация: 30.01.2014
Сообщений: 12,307
15.04.2014, 14:15 9
IrineK, Он вроде operator+ реализует, а не +=.
В его реализации и в вашей одна и та же проблема. Которая, впрочем, не относится к теме. Но тем не менее:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    String & operator += (const String &s)
    {   String temp (*this);
 
        if (str != NULL)
        {   delete [] str;
            str = NULL;
        }
 
        len = temp.len + s.len;
        str = new char [len + 1];
        strncpy (str, temp.str, temp.len+1); // <------- проблема, если temp.str - NULL
        strncat (str, s.str, s.len+1);
        return *this;
    }
Вот в таком коде:
C++
1
2
3
4
5
6
7
int main()
{
    String a;
    String b("test", 4);
 
    a += b;
}
1
Заблокирован
15.04.2014, 14:29 10
Цитата Сообщение от DrOffset Посмотреть сообщение
Он вроде operator+ реализует, а не +=.
В данном контексте - именно += (так органичней - хотя, дело вкуса).

Добавлено через 1 минуту
Цитата Сообщение от DrOffset Посмотреть сообщение
Вот в таком коде:
Сейчас допилим.

Добавлено через 3 минуты
Кликните здесь для просмотра всего текста
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
#include <iostream>
 
class String
{
public:
    String (): len(0), str(NULL) {}
    String (const char *_str, int _len) : len (_len)
    {   str = new char [len + 1];
        strncpy (str, _str, _len+1);
    }
 
    String (const String &s) : len (s.len)
    {   str = new char [len + 1];
        strncpy (str, s.str, s.len+1);
    }
 
    ~String ()
    {   delete [] str;
    }
 
    String &operator = (const String &s)
    {   if (str == s.str && len == s.len) 
        return *this;
     
        if (str != NULL)
        {   delete [] str;
            str = NULL;
        }
        len = s.len;
        str = new char [len + 1];
        strncpy (str, s.str, s.len+1);
        return *this;
    }
 
    String &operator += (const String &s);
    String &operator += (const char *s);
 
    friend std::ostream &operator <<(std::ostream & os, const String &s);
 
private:
    int len;
    char *str;
};
 
String &String :: operator += (const String &s)
{   if (str == NULL)
    {   *this = s;
        return *this;
    }
 
    String temp (*this);
    delete [] str;
    str = NULL;
 
    len = temp.len + s.len;
    str = new char [len + 1];
    strncpy (str, temp.str, temp.len+1);
    strncat (str, s.str, s.len+1);
    return *this;
}
 
std::ostream &operator <<(std::ostream & os, const String &s)
{   os << s.str;
    return os;
}
 
 
int main()
{   String s1 ("12345", 5);
    String s2 ("999", 3);
    std :: cout << s1 << " " << s2 << '\n';
    s1 += s2;
    std :: cout << s1 << '\n';
 
    s2 = s1;
    std :: cout << s2 << '\n';
 
    s2 += s1;
    std :: cout << s2 << '\n';
 
    String a;
    String b("test", 4);
 
    a += b;
    std :: cout << a << '\n';
 
    std::cin.get();
    return 0;
}


Добавлено через 7 минут
Цитата Сообщение от DrOffset Посмотреть сообщение
одна и та же проблема
Еще проблемы?
0
13712 / 7335 / 1751
Регистрация: 30.01.2014
Сообщений: 12,307
15.04.2014, 14:42 11
Цитата Сообщение от IrineK Посмотреть сообщение
В данном контексте - именно += (так органичней - хотя, дело вкуса).
Я исхожу из того, что спрашивает автор Он же как бы "Заказчик" в этой ситуации. А если уж говорить об органичности, то у нормального класса String должны быть все операторы, и + и +=. Хотя бы потому, что решают немного разные задачи.

Лично мне кажется, что темповый объект здесь лишний. Т.к. он конструируется через копирование, следовательно еще раз вызывается new, хотя оно не нужно по большому счету.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    String & operator+=(const String & s)
    {
        if(s.str != NULL)
        {
            char * buf = new char[len + s.len + 1];
            if(str != NULL)
            {
                strncpy(buf, str, len + 1);
            }
            strncat(buf, s.str, s.len + 1);
            len += s.len;
            delete [] str;
            str = buf;
        }
        return *this;
    }
Добавлено через 5 минут
Собственно strncat тут тоже не особо нужен, потому что у нас и так есть конец строки, куда надо дописывать (strncat же его еще сначала должен найти).
Вместо 10й строки можно просто написать так:
C++
1
            strncpy(buf + len, s.str, s.len + 1);
0
Заблокирован
15.04.2014, 14:43 12
А теперь проверьте на собственный тест )
0
13712 / 7335 / 1751
Регистрация: 30.01.2014
Сообщений: 12,307
15.04.2014, 14:46 13
Цитата Сообщение от IrineK Посмотреть сообщение
А теперь проверьте на собственный тест )
Это к чему?
0
Заблокирован
15.04.2014, 14:54 14
У вас проблема, если str == NULL
0
13712 / 7335 / 1751
Регистрация: 30.01.2014
Сообщений: 12,307
15.04.2014, 14:59 15
Цитата Сообщение от IrineK Посмотреть сообщение
У вас проблема, если str == NULL
Где же? Если s.str == NULL мы не войдем вообще в условие, будем считать, что к строке ничего не добавилось.
Если s.str != NULL, но str == NULL, то мы не войдем во второе условие и началом строки будет содержимое из s.str.
Проблемы нет, или поясните что имеется в виду тогда
0
Заблокирован
15.04.2014, 15:00 16
Проблема исчезнет, если вы обязательно замените 10-ю строку на strncpy.
strncat с пустой строкой не работает.
2
13712 / 7335 / 1751
Регистрация: 30.01.2014
Сообщений: 12,307
15.04.2014, 16:05 17
Цитата Сообщение от IrineK Посмотреть сообщение
strncat с пустой строкой не работает.
Согласен

Добавлено через 56 минут
Цитата Сообщение от IrineK Посмотреть сообщение
Еще проблемы?
Для завершенности:
Та же самая, но в операторе присваивания, если s.str == NULL.
Оператор вывода, тоже не учитывает NULL.
1
Заблокирован
15.04.2014, 16:59 18
DrOffset,
Как лучше среагировать на присвоение строки с нулевым указателем?
Проигнорировать или присвоить?

Добавлено через 32 минуты
Решила не игнорировать.

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
#include <iostream>
 
class String
{
public:
    String (): len(0), str(NULL) {}
    
    String (const char *_str, int _len) : len(_len)
    {   if (_len > strlen(_str))
            len = strlen(_str);
        str = new char [len + 1];
        strncpy (str, _str, len+1);
        str[len] = '\0';
    }
 
    String (const String &s)
    {   if(s.str != NULL)
        {   len = s.len;
            str = new char [len + 1];
            strncpy (str, s.str, s.len+1);
        }
        else
        {   len = 0; str = NULL; }
    }
 
    ~String ()
    {   delete [] str;
    }
 
    String &operator = (const String &s)
    {   if(s.str != NULL)
        {   if (str == s.str && len == s.len) 
            return *this;
     
            if (str != NULL)
            {   delete [] str;
                str = NULL;
            }
            len = s.len;
            str = new char [len + 1];
            strncpy (str, s.str, s.len+1);
        }
        else 
        {   delete [] str;
            str = NULL;
            len = 0;
        }
        return *this;
    }
 
    String &operator += (const String &s);
    String &operator += (const char *s);
 
    friend std::ostream &operator <<(std::ostream & os, const String &s);
 
private:
    int len;
    char *str;
};
 
String &String :: operator += (const String &s)
{  if(s.str != NULL)
   {    char * buf = new char[len + s.len + 1];
        if(str != NULL)
            strncpy(buf, str, len + 1);
        strncpy(buf + len, s.str, s.len + 1);
        len += s.len;
        delete [] str;
        str = buf;
   }
   return *this;
}
 
std::ostream &operator <<(std::ostream & os, const String &s)
{   if (s.str != NULL)
        os << s.str << " " << s.len;
    else
        os << "NULL  0";
    return os;
}
 
 
int main()
{   String s1 ("12345", 5);
    String s2 ("999", 3);
    std :: cout << s1 << '\n' << s2 << '\n';
    s1 += s2;
    std :: cout << s1 << '\n';
 
    s2 = s1;
    std :: cout << s2 << '\n';
 
    s2 += s1;
    std :: cout << s2 << '\n';
 
    String a;
    s1 = a;
    std :: cout << s1 << '\n';
    
    String b("test", 8);
    std :: cout << b<< '\n';
 
    b += b;
    std :: cout << b<< '\n';
 
    String d(a);
    std :: cout << d<< '\n';
 
    std::cin.get();
    return 0;
}
1
36 / 36 / 27
Регистрация: 05.11.2013
Сообщений: 149
15.04.2014, 18:01  [ТС] 19
Спасибо всем отписавшимся.
0
108 / 108 / 23
Регистрация: 21.03.2010
Сообщений: 445
15.04.2014, 18:08 20
почему-то прочитал топик, стало интересно - зачем в Qt такой класс? В std::string есть ряд неудобных операций вроде вывода символа в строку и всё такое, но в QString всё куда проще и, судя по предложенным решениям, надёжнее, чем в независимой реализации...
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.04.2014, 18:08

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

UDP работает из-по QtCreator, но не работает в сборке
Добрый день. Столкнулся со следующей проблемой. Использую QUdpSocket для отправки пакетов на другое...

В QtCreator не работает qmake (linux)
Здравствуйте! При сборке проекта, в консоли сборки выдает следующие сообщения: 11:23:46:...

QtCreator release не работает winapi
Всем привет! Вот интереснейший случай. Выполняю программу в debug режиме win api функция работает...

Установка Qt и QtCreator через терминал, не работает 'help'
Поставил QtCreator через терминал, не пашет 'help') Добавлено через 40 секунд Поищу...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

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