crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> работа с class
astra
  опции профиля:
сообщение 7.2.2014, 14:45
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 7.2.2014
Пользователь №: 4050

Спасибо сказали: 0 раз(а)




Репутация:   0  


Не хотел создавать тему, но пришлось...

реализую вот такие вещи (черновичок - отладка алгоритма):
*.h
Раскрывающийся текст

class messageBlock
{
public:
    QString str0, str1, str2, str3;
    char *mesblock0, *mesblock1, *mesblock2, *mesblock3;
    messageBlock()
    {
        str0 = QObject::tr("String0");
        str1 = QObject::tr("String1");
        str2 = QObject::tr("String2");
        str3 = QObject::tr("String3");
        mesblock0 = str0.toUtf8 ().data ();
        mesblock1 = str1.toUtf8 ().data ();
        mesblock2 = str2.toUtf8 ().data ();
        mesblock3 = str3.toUtf8 ().data ();
    }
};


*.cpp
Раскрывающийся текст

int main( int argc, char** argv )
{
    setlocale(LC_ALL, "rus");
    QApplication a( argc, argv );

    QTranslator trans;
    trans.load ( "exe_ru" );
    a.installTranslator ( &trans );

    messageBlock MsgBlk;

    FILE*   fdd;
    fdd = fopen ( "file_dat", "wt");

    fprintf ( fdd, MsgBlk.mesblock0 );
    fprintf ( fdd, MsgBlk.mesblock1 );
    fprintf ( fdd, MsgBlk.mesblock2 );
    fprintf ( fdd, MsgBlk.mesblock3 );

    fclose( fdd );
    return a.exec();
}


с помощью лингвиста перевожу...

и на выходе получаю
"строка3строка3строка3строка3"

а должно присваиваться
"строка0строка1строка2строка3".

укажите на мои ошибки. благодарю

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
crot26rus
  опции профиля:
сообщение 7.2.2014, 22:19
Сообщение #2


Новичок


Группа: Новичок
Сообщений: 9
Регистрация: 4.4.2010
Пользователь №: 1593

Спасибо сказали: 5 раз(а)




Репутация:   0  


вот здесь твои ошибки:
mesblock0 = str0.toUtf8 ().data ();
mesblock1 = str1.toUtf8 ().data ();
mesblock2 = str2.toUtf8 ().data ();
mesblock3 = str3.toUtf8 ().data ();


toUtf8() создаёт QByteArray, в котором хранятся данные и на каждой следующей строчке старый объект удаляется и создаётся новый.
В итоге все указатели хранят один и тот же адрес и указывают на область памяти, которая уже освобождена (теперь там хранится мусор: последние записанные туда данные).

P.S. может я не совсем правильно описал происходящие процессы (знающих людей прошу поправить), но надеюсь моя мысль понятна.



Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
astra
  опции профиля:
сообщение 8.2.2014, 0:08
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 7.2.2014
Пользователь №: 4050

Спасибо сказали: 0 раз(а)




Репутация:   0  


crot26rus,
Благодарю, скорей всего ты прав, не догадался об этом...

решил сей вопрос:
Раскрывающийся текст

class messageBlock
{
public:
    QString str0, str1, str2, str3;
    char *mesblock0, *mesblock1, *mesblock2, *mesblock3;
    QByteArray array0, array1, array2, array3,;
    messageBlock()
    {
        str0 = QObject::tr("String0");
        array0 = str0.toUtf8();
        str1 = QObject::tr("String1");
        array1 = str1.toUtf8();
        str2 = QObject::tr("String2");
        array2 = str2.toUtf8();
        str3 = QObject::tr("String3");
        array3 = str3.toUtf8();
        mesblock0 = array0.data ();
        mesblock1 = array1.data ();
        mesblock2 = array2.data ();
        mesblock3 = array3.data ();
    }
};


но что то внешне как-то громоздко получается... у меня будет намного больше строк.
Не знаю стоит ли здесь задавать этот вопрос, или перенесите тему в нужный подфорум, но вопрос таков: "есть ли более изящное решение ?"
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ilyabvt
  опции профиля:
сообщение 8.2.2014, 7:34
Сообщение #4


Активный участник
***

Группа: Участник
Сообщений: 297
Регистрация: 23.6.2011
Пользователь №: 2765

Спасибо сказали: 45 раз(а)




Репутация:   3  


Если говорить о старом коде то можно сделать так:
strcpy(mesblock0, str0.toUtf8 ().data ());
strcpy(mesblock1, str1.toUtf8 ().data ());
strcpy(mesblock2, str2.toUtf8 ().data ());
strcpy(mesblock3, str3.toUtf8 ().data ());

Вся проблема в том что в старом коде шло копирование указателей, а не строк. "str0.toUtf8 ()" создает временный объект который после выражения
mesblock0 = str0.toUtf8 ().data ();
будет уничтожен. Соответственно нужно скопировать строку, а не ее адрес. А перед эти еще и выделить достаточно памяти. Т.е. mesblock0 должен быть либо массивом достаточного размера, либо в конструкторе messageBlock нужно выделять память из кучи. Учитывая дополнительные операции выделения/освобождения памяти, такое решение трудно будет назвать изящным.

Цитата
mesblock0 = array0.data ();
mesblock1 = array1.data ();
mesblock2 = array2.data ();
mesblock3 = array3.data ();

Ну и смысл в этом коде? Тут прямой ошибки нет, но зачем лишний указатель. Используйте тогда уж везде "array0.data ()" типа такого:
fprintf ( fdd, MsgBlk.array0.data () );

Тогда кстати не придется забивать голову выделением памяти.
P.S. QByteArray в данном контексте тоже в принципе не обязателен. Можно сделать так:
    fprintf ( fdd, MsgBlk.str0.toUtf8().data());
    fprintf ( fdd, MsgBlk.str1.toUtf8().data());
    fprintf ( fdd, MsgBlk.str2.toUtf8().data());
    fprintf ( fdd, MsgBlk.str3.toUtf8().data());


Сообщение отредактировал ilyabvt - 8.2.2014, 7:53
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
astra
  опции профиля:
сообщение 8.2.2014, 9:41
Сообщение #5


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 7.2.2014
Пользователь №: 4050

Спасибо сказали: 0 раз(а)




Репутация:   0  


ilyabvt, Спасибо я рассмотрю, предложенный тобой вариант. =)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 10.2.2014, 13:28
Сообщение #6


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


А еще неплохо было бы оптимизировать твой код, примерно так:
Код
class messageBlock
{
public:
    static const int ARRAY_SIZE = 4;
    QString str[ARRAY_SIZE];
    char *mesblock[ARRAY_SIZE];
    messageBlock()
    {
        for( int n = 0; n < ARRAY_SIZE;++n)
        {
            str[n] = QObject::tr("String%1").arg(n);
            QByteArray tmpBa = str[n].toUtf8();
            mesblock[n] = tmpBa.data ();
        }
    }
};

int main( int argc, char** argv )
{
    setlocale(LC_ALL, "rus");
    QApplication a( argc, argv );

    QTranslator trans;
    trans.load ( "exe_ru" );
    a.installTranslator ( &trans );

    messageBlock MsgBlk;

    FILE*   fdd;
    fdd = fopen ( "file_dat", "wt");

    for( int n = 0; n < messageBlock::ARRAY_SIZE;++n)
        fprintf ( fdd, MsgBlk.mesblock[n] );

    fclose( fdd );
    return a.exec();
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
astra
  опции профиля:
сообщение 11.2.2014, 21:28
Сообщение #7


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 7.2.2014
Пользователь №: 4050

Спасибо сказали: 0 раз(а)




Репутация:   0  


ViGOur, ооо я благодарю тебя за оптимизацию, но я думал как бы это сделать, но у меня задача в том что будет около 14-18 строк с разной информацией, грубо говорят по выполнению моей бооольшой программы, у меня создается внешний файл с инфой, а этот пример- промакашка(проба способов использования Qtlinguist).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
astra
  опции профиля:
сообщение 13.2.2014, 10:02
Сообщение #8


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 7.2.2014
Пользователь №: 4050

Спасибо сказали: 0 раз(а)




Репутация:   0  


не учел детали основного кода, не могу разобраться, схема такая

Раскрывающийся текст

void PrintfMessageFile(char* fileOut, class MSgblk);

class messageBlock
{
public:
    QString str0, str1, str2, str3;
    char *mesblock0, *mesblock1, *mesblock2, *mesblock3;
    QByteArray array0, array1, array2, array3,;
    messageBlock()
    {
        str0 = QObject::tr("String0");
        array0 = str0.toUtf8();
        str1 = QObject::tr("String1");
        array1 = str1.toUtf8();
        str2 = QObject::tr("String2");
        array2 = str2.toUtf8();
        str3 = QObject::tr("String3");
        array3 = str3.toUtf8();
        mesblock0 = array0.data ();
        mesblock1 = array1.data ();
        mesblock2 = array2.data ();
        mesblock3 = array3.data ();
    }
};



Раскрывающийся текст

int main( int argc, char** argv )
{
    setlocale(LC_ALL, "rus");

    QApplication a( argc, argv );

    QTranslator trans;
    trans.load ( "exe_ru" );
    a.installTranslator ( &trans );

    messageBlock MsgBlk;

    char          file_dat [ 12 ] = "fileOut";

    PrintfMessageFile( file_dat , MsgBlk);

    return a.exec();
}



Раскрывающийся текст

#include <messageBlock.h>

FILE*   fdd;

void PrintfMessageFile (char *fileOut, class MSgblk)
{
    fdd= fopen ( fileOut , "wt");


    fprintf ( fdd, MsgBlk.mesblock0 );
    fprintf ( fdd, MsgBlk.mesblock1 );
    fprintf ( fdd, MsgBlk.mesblock2 );
    fprintf ( fdd, MsgBlk.mesblock3 );

    flose(fdd);

}



ошибка вот такая :
main.cpp: In function 'int main(int, char**)':
main.cpp:32:41: error: parameter 2 of 'void PrintfMessageFile(char*, MSgblk)' has incomplete type 'MSgblk'

Не очень понимаю ошибку. Вообще как лучше сделать в данной ситуации?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
crot26rus
  опции профиля:
сообщение 13.2.2014, 12:58
Сообщение #9


Новичок


Группа: Новичок
Сообщений: 9
Регистрация: 4.4.2010
Пользователь №: 1593

Спасибо сказали: 5 раз(а)




Репутация:   0  


Цитата
void PrintfMessageFile (char *fileOut, class MSgblk)

должно быть, например, так:
Цитата
void PrintfMessageFile (char *fileOut, const MSgblk& blk)
{
fdd= fopen ( fileOut , "wt");

fprintf ( fdd, blk.mesblock0 );
/// ...
flose(fdd);
}


Цитата(crot26rus @ 13.2.2014, 13:53) *
Цитата
void PrintfMessageFile (char *fileOut, class MSgblk)

должно быть, например, так:
Цитата
void PrintfMessageFile (char *fileOut, const MSgblk& blk)
{
fdd= fopen ( fileOut , "wt");

fprintf ( fdd, blk.mesblock0 );
/// ...
flose(fdd);
}



Поторопился, вот правильный вариант:
void PrintfMessageFile (char *fileOut, const messageBlock& blk)
{
    fdd= fopen ( fileOut , "wt");

    fprintf ( fdd, blk.mesblock0 );
    /// ...
    flose(fdd);
}



Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 16.4.2024, 12:43