Russian Qt Forum
Ноябрь 24, 2024, 15:04 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: Как в QString сменить указатель на массив данных ?  (Прочитано 27464 раз)
SABROG
Гость
« : Май 28, 2007, 09:11 »

Я пишу программу, которая работает с XMLем, парсер создает дерево XMLя в памяти, где ветки имеют указатели на данные, ключи и параметры типа unsigned char. Т.к. XML это большой массив текстовых данных в памяти, то мне бы не хотелось для работы с этими данными весь текст копировать опять но уже в класс QString. Возможно ли создать экземпляр объекта класса QString куда можно передать только указатель на текстовую zero-null строку в формате UTF8, таким образом чтобы доступ к ней осуществлялся как по обычному указателю (unsigned char *) так и через класс QString ? Т.е. если я что-то меняю через указатель (unsigned char *), то строка в классе QString тоже будет менятся. Нужно это все для экономии памяти и скорости при работе с XMLем.

добавлено спустя 8 минут:

 Вроде нашел решение:

Цитировать

QString QString::fromRawData ( const QChar * unicode, int size )   [static]
Constructs a QString that uses the first size Unicode characters in the array unicode. The data in unicode is not copied. The caller must be able to guarantee that unicode will not be deleted or modified as long as the QString (or an unmodified copy of it) exists.
Any attempts to modify the QString or copies of it will cause it to create a deep copy of the data, ensuring that the raw data isn't modified.
Here's an example of how we can use a QRegExp on raw data in memory without requiring to copy the data into a QString:
      QRegExp pattern;
      static const QChar unicode[] = {
              0x005A, 0x007F, 0x00A4, 0x0060,
              0x1009, 0x0020, 0x0020};
      int size = sizeof(unicode) / sizeof(QChar);

      QString str = QString::fromRawData(unicode, size);
      if (str.contains(QRegExp(pattern))) {
          // ...
      }
Warning: A string created with fromRawData() is not '\0'-terminated, unless the raw data contains a '\0' character at position size. This means unicode() will not return a '\0'-terminated string (although utf16() does, at the cost of copying the raw data).
Записан
Alex03
Гость
« Ответ #1 : Май 28, 2007, 11:50 »

Ежели у Вас данные в UTF-8 то оно никак с const QChar * unicode не кореллирует.
Возможно Вам подойдёт QCString?
Записан
SABROG
Гость
« Ответ #2 : Май 28, 2007, 12:44 »

QCString уже не поддерживается:

Цитировать

Q3CString(const char *str, uint max) constructs a string of length strlen(str) or max - 1, whichever is shorter. QByteArray(const char *data, int size) constructs a byte array containing exactly size bytes.
For example, if you have code like
     QCString str1("Hello", 4);           // "Hel"
     QCString str2("Hello world!", n);
you can rewrite it as
     QByteArray str1("Hello", 3);
     QByteArray str2("Hello world!");
     str2.truncate(n - 1);


Еще такой вопрос. Есть у меня метод:

Код:
QString & TForm::escaped(QString &sql)
{
    return sql.replace(QLatin1String("'"),QLatin1String("''")).prepend(QLatin1String("'")).append(QLatin1String("'"));
}


Я пытаюсь в него передать строку таким макаром:
Код:

main->escaped( leEditBox->text() );


Но получаю ошибку, что нельзя преобразовать QString в QString&. Я почему-то всегда считал, что указывая непосредственно экземпляр класса я неявно передаю ссылку на него:

Код:

QString txt = "HOTEL'S";
escaped(txt);


Этот кусок работает как надо, также как и этот:

Код:

QString leEditBoxText(leEditBox->text());
main->escaped( leEditBoxText );


Почему же без посредников не компилит ?
Записан
Tonal
Гость
« Ответ #3 : Май 28, 2007, 13:03 »

const в сигнатуре функции забыл.
Записан
SABROG
Гость
« Ответ #4 : Май 28, 2007, 13:20 »

Сделал так:

Код:

QString & TForm::escaped(const QString &sql)


Только ругается на эту строку:

Код:

return sql.replace(QLatin1String("'"),QLatin1String("''")).prepend(QLatin1String("'")).append(QLatin1String("'"));


Цитировать

src\TForm.cpp: In member function `QString& TForm::escaped(const QString&)':
src\TForm.cpp:1355: error: passing `const QString' as `this' argument of `QStrin
g& QString::replace(const QString&, const QString&, Qt::CaseSensitivity)' discar
ds qualifiers


Понять не могу че ему не нравится.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #5 : Май 28, 2007, 13:43 »

Цитата: "SABROG"

Понять не могу че ему не нравится.


У тебя оъявлена константная ссылка на объект. При этом,  значение этого объекта не может быть изменено. По сути, это объявление делает константным сам объект.
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Вудруф
Гость
« Ответ #6 : Май 28, 2007, 13:45 »

Хмм?
Код:
QString tmp = sql;
return tmp.replace (...);
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #7 : Май 28, 2007, 13:48 »

все верно, sql у тя константа теперь, а метод QString::replace не имеет модификатора const. Т.е. он должен изменять sql, но она же у тебя константная.
делай как Вудруф говорит.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
SABROG
Гость
« Ответ #8 : Май 28, 2007, 14:00 »

В заблуждение меня вводите Показает язык
Сделал как Вудруф предложил, думал replace создает новый объект класса QString, а старый оставляет неизменным. Ну раз это не так, то действительно оригинальные строки лучше оставлять неизменными, тем более что возможна передача константных объектов.

Еще вот чего я понять не могу:

Код:

QString & TForm::escaped(const QString &sql)
{
    QString tmp = sql;
    return tmp.replace(QLatin1String("'"),QLatin1String("''")).prepend(QLatin1String("'")).append(QLatin1String("'"));
}


Если я создаю объект класса QString в стеке, то при выходе из процедуры он должен уничтожится и вернется ссылка на несуществующий объект, разве нет ? Угу, значит надо через new делать, но вот кто будет потом освобождать память, мне влом как-то Улыбающийся
Записан
goer
Гость
« Ответ #9 : Май 28, 2007, 14:56 »

Возвращай в таком случае сам объект а не ссылку на него.
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #10 : Май 28, 2007, 15:08 »

как вариант сделай
void TForm::escaped(QString &sql)
{
sql = sql.replace(QLatin1String("'"),QLatin1String("''")).prepend(QLatin1String("'")).append(QLatin1String("'"));}

и передавай в качестве параметра строку, которая должна модифицироваться...
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
SABROG
Гость
« Ответ #11 : Май 28, 2007, 16:09 »

Спасибо за варианты. Я сделал как предложил goer, все-таки у меня возможна передача константных строк, которым нельзя сделать replace. А учитывать это каждый раз в коде копируя строки не хочется. Поэтому пусть уж копируются  внутри процедуры.
Записан
goer
Гость
« Ответ #12 : Май 28, 2007, 16:45 »

А чтобы SABROG не мучала совесть по поводу эффективности использования копирования строк, могу сообщить ему что в кути применяется такая замечательнаяя технология как Implicitly Sharing, из за которой глубокого копирования при возвращении строки не будет. Скопируется только указатель на данные, которым и завладеет объект-получатель значения функции.
Записан
SABROG
Гость
« Ответ #13 : Май 28, 2007, 16:57 »

Насчет deep copying я почитал и понял такую вещь, если нигде в коде не меняются данные переданные из одного QString в другой QString, то копирования не происходит, но если же происходят операции со строками, то да, идет "глубокое копирование"
Записан
Mikhail
Программист
*****
Offline Offline

Сообщений: 587


Просмотр профиля
« Ответ #14 : Май 28, 2007, 19:31 »

to SABROG

Цитировать

Еще такой вопрос. Есть у меня метод:
Код:
QString & TForm::escaped(QString &sql)
{
    return sql.replace(QLatin1String("'"),QLatin1String("''")).prepend(QLatin1String("'")).append(QLatin1String("'"));
}



Я пытаюсь в него передать строку таким макаром: Код:

main->escaped( leEditBox->text() );



Но получаю ошибку, что нельзя преобразовать QString в QString&. Я почему-то всегда считал, что указывая непосредственно экземпляр класса я неявно передаю ссылку на него:
Код:

QString txt = "HOTEL'S";
escaped(txt);


Вопрос в том какой у тебя компилятор.
Если MSVC то он проглотит оба варианта.
Скорее всего у тебя MinGW либо gcc
Записан
Страниц: [1] 2 3 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.071 секунд. Запросов: 22.