Я застреваю в printf проблеме. Я ценил бы, если я могу получить некоторую справку здесь: В ниже кода, я вижу, что семейство шрифтов перемещается правильно в первом printf (), но если я установил его на переменную, я только получаю пустую строку. Как я могу поместить его в переменную и иметь правильные значения? Я просто не хочу вводить 'font.family () .family () .string () .utf8 () .data ()' везде?
Я сделал это в том же методе:
void myMethod() {
const char* fontFamily = font.family().family().string().utf8().data();
// get displayed correctly
printf ("drawText1 %s \n", font.family().family().string().utf8().data());
// get an empty string
printf ("drawText2 %s \n", fontFamily);
}
И подпись 'данных ()'
class CString {
public:
CString() { }
CString(const char*);
CString(const char*, unsigned length);
CString(CStringBuffer* buffer) : m_buffer(buffer) { }
static CString newUninitialized(size_t length, char*& characterBuffer);
const char* data() const;
//...
}
Подпись utf8 ()
class String {
CString utf8() const;
}
Спасибо.
Что-то в цепочке font.family().family().string().utf8().data()
возвращает временный объект. В вашем первом printf
временный объект не выходит из области видимости, пока не вернется printf
. Во втором printf
временный объект был уничтожен после присвоения указателя, и теперь указатель недействителен. Вы видите классический пример "неопределенного поведения".
Есть два способа исправить это. Либо сделать копию данных до того, как временный объект будет уничтожен, либо сделать ссылку на временный объект. Копия, вероятно, самый простой и понятный способ, если только класс имеет оператор копирования. Если предположить, что utf8()
создает временный CString
, это будет
CString fontFamily = font.family().family().string().utf8();
printf ("drawText2 %s \n", fontFamily.data());
Вы кэшируете указатель, который находится во временном элементе, возвращаемом utf8 ()
(как утверждали Марк и Нил). Вам нужно будет изменить fontFamily
либо на CString
, либо на const CString &
, чтобы сохранить результат от utf8 ()
в области видимости.
Вызов data ()
(при условии, что он вызывается для std :: string) не обязательно возвращает строку с завершающим нулем. Вам почти наверняка понадобится c_str ()
, который определен для этого.