×

Discussion Board

Results 1 to 8 of 8
  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    94

    Запись в файл русских символов

    Доброе утро
    Хотелось бы получить консультацию по следующему вопросу:
    При помощи ниже приведенного диалога получаю данные и затем при определенных условиях пишу их в файл. В случае если язык ввода для диалога NameDlg выбран английский то все замечательно пишется и читается. Но в случае если язык ввода (в виртуальной клавиатуре телефона 5800)выбран русский (или инной другой) то в файл в этом случае пишутся символы с кодом 01.


    RFs fsSession;
    RFile Ft;
    TBuf16<20> sName;
    CAknFileNamePromptDialog* NameDlg = CAknFileNamePromptDialog::NewL();
    NameDlg->SetTitleL(_L("Enter Name:"));
    NameDlg->SetRightSoftkeyL(_L("Cancel"));
    NameDlg->SetLeftSoftkeyL(_L("Save"));

    sName.Zero();
    DialogResult = NameDlg->ExecuteL(sName);

    ----------------//----------------------
    ----------------//----------------------
    ----------------//----------------------
    fsSession.Connect();
    iErr = Ft.Replace(fsSession,sFullFileName,EFileShareAny|EFileWrite);
    if(iErr == KErrNone)
    {
    User::LeaveIfError(Ft.Write(sName));

    Причем ф-цией DrawText, Данные полученные в русской кодировке нормально выводятся на экран. И изображение на экране, вполне адекватное.

    1) Проблема в использовании диалога?
    2) Проблема в какой то “неправильной” записи в файл?

  2. #2
    Nokia Developer Moderator
    Join Date
    Jun 2007
    Location
    Moscow, Russia
    Posts
    1,355

    Re: Запись в файл русских символов

    А вы чем файл просматриваете? Уверены что ваш вьювер корректно показывает юникод?

  3. #3
    Registered User
    Join Date
    Nov 2008
    Posts
    94

    Re: Запись в файл русских символов

    Доброе утро

    А вы чем файл просматриваете? Уверены что ваш вьювер корректно показывает юникод?

    truf, простите но не совсем понял Ваш вопрос.

    Я при помощи приведенного диалога
    sName.Zero();
    DialogResult = NameDlg->ExecuteL(sName); пытаюсь получить текстовое данное. и при вызове в диалоге виртуальной клавиатуры получаю, в случае с английской раскладкой, нормальное преобразуемое в дальнейшем данное.Переменная sName, в случае если раскладка английская, содержит "корректные" символы. (например result001или temp003). В случае если раскладка выбрана русская то Переменная sName содержит ( насколько я понимаю юникод) символы. Эти данные, и в случае английской и в случае русской раскладки, нормально выводятся на экран телефона ф-цией DrawText. Но вывод на экран для меня даже не вторичен. Мне потом эти полученные данные необходимо писать в файл. И вот тут тут и происходит моя проблема.
    При вот такой вот записи в файл.
    fsSession.Connect();
    iErr = Ft.Replace(fsSession,sFullFileName,EFileShareAny|EFileWrite);
    if(iErr == KErrNone)
    {
    User::LeaveIfError(Ft.Write(sName));
    В файл записываются символы с кодом "01".
    (записал такой файл, скачал на комп и посмотрел что пишется)

    Поэтому вопрос: как при записи в файл обойти стороной проблему записи юникода?
    То есть как "правильно" писать в файл?

  4. #4
    Nokia Developer Moderator
    Join Date
    Jun 2007
    Location
    Moscow, Russia
    Posts
    1,355

    Re: Запись в файл русских символов

    Да нет там никакой проблемы записи юникода. Нет ни у кого. Symbian везде и всегда по умолчанию использует юникод. И английские данные вы тоже получаете в юникод, и пишите их в юникод, и файл у вас всегда будет в юникод. Потомучто TBuf16 - дескриптор для хранения Unicode символов.

    Прикрепите файл к сообщению, ил выложите на бесплатном хостинге и дайте ссылку. И покажите код до конца, а то он обрывается. И если вот это -
    ----------------//----------------------
    ----------------//----------------------
    ----------------//----------------------
    опущенные участки кода, то показывайте и их.

  5. #5
    Registered User
    Join Date
    Nov 2008
    Posts
    94

    Re: Запись в файл русских символов

    Доброе утро
    Truf, благодаря Вам и хелпу смог преодолеть на половину данную ситуацию (неправильный вывод русских символов) для симулятора. Но для второй половины не хватает понимания.
    1) Ниже приведенная функция, на симуляторе, и пишет и читает в/из файла (смотрел в отладчике) русские символы. Но при выводе на экран, происходит вывод “арабской вязи” а не русских символов, в обоих случаях вывода.
    2) Эта же функция на телефоне все равно записывает в файл и соответственно уже читает из файла символы с кодом 0x01. В чем моя ошибка?
    3) Эта функция на телефоне при первом выводе на экран осуществляет нормальную печать русских символов, а второй случай не могу проверить из за кода 0x01.

    В чем моя ошибка? Не могли бы Вы помочь в осознании того в чем я ошибаюсь?

    4) Причем это одинаково происходит на двух телефонах 5800. Дома стоит карбид версии 2, билд 014 пак 3. На работе поставил карбид версии 2, билд 014 пак 5. Симуляторы ведут себя идентично по отношению к этой функции. Но если дома, на третьем паке, я могу объявить следующую декларацию _LIT8(KEngenName1,"В И Ленин;");в инклюд файле. То на рабочем компьютере, где поставил пятый пак. Карбид при попытке компиляции выдает ошибку что “CP1251 не поддерживает”. Хотя encoding и дома и на работе стоит один и тот же “Default(inherited from container CP1251)”. В чем может быть проблема?


    void CUTestGridControl::Test11()
    {

    TBool DialogResult;
    TBuf16<20> sName;
    TPoint TextPoint;
    TBuf16<20> sHeroesName;
    TBuf8<20> sName1,sT;
    RFs fsSession;
    RFile Ft;
    TInt iErr,iCount;
    TFileName sFullFileName;

    TextPoint.iX = 20;
    TextPoint.iY = 30;

    _LIT(KDefaultDirCName,"C:\\test.txt");
    CAknFileNamePromptDialog* NameDlg = CAknFileNamePromptDialog::NewL();
    NameDlg->SetTitleL(_L("Enter Your Name:"));
    NameDlg->SetRightSoftkeyL(_L("Cancel"));
    NameDlg->SetLeftSoftkeyL(_L("Save"));
    _LIT(KUserName,"No Name");

    sName.Zero();
    DialogResult = NameDlg->ExecuteL(sName);

    if (sName.Length()>12)
    {
    sName = sName.Mid(0,12);
    }

    sHeroesName.Zero();
    sHeroesName.Copy(sName);

    if (sHeroesName.Length()>12)
    {
    sHeroesName = sHeroesName.Mid(0,12);
    }
    // Первый вывод
    iBgc->DrawText(sHeroesName, TextPoint);


    User::LeaveIfError(fsSession.Connect());
    iErr = Ft.Replace(fsSession,KDefaultDirCName,EFileWrite);
    if(iErr == KErrNone)
    {
    sName1.Zero();
    sName1.Copy(sHeroesName);
    User::LeaveIfError(Ft.Write(sName1));
    User::LeaveIfError(Ft.Flush()); // Commit data

    Ft.Close();
    fsSession.Close();

    }

    fsSession.Connect();
    iErr = Ft.Open(fsSession,KDefaultDirCName,EFileRead);

    Ft.Size(iCount);
    User::LeaveIfError(Ft.Read(sT,iCount));
    User::LeaveIfError(Ft.Flush()); // Commit data
    Ft.Close();
    fsSession.Close();

    TextPoint.iY += 30;

    sHeroesName.Zero();
    sHeroesName.Copy(sT);

    if (sHeroesName.Length()>12)
    {
    sHeroesName = sHeroesName.Mid(0,12);
    }
    // второй вывод
    iBgc->DrawText(sHeroesName, TextPoint);


    }

  6. #6
    Nokia Developer Moderator
    Join Date
    Jun 2007
    Location
    Moscow, Russia
    Posts
    1,355

    Re: Запись в файл русских символов

    Code:
    void CUTestGridControl::Test1L() -В функции возможен сброс,
     соблюдаем соглашение об именовании
    {
    
    TBool DialogResult;
    TBuf16<20> sName; - используем TBuf вместо TBuf16
    TPoint TextPoint;
    TBuf16<20> sHeroesName;
    TBuf8<20> sName1,sT;
    RFs fsSession;
    RFile Ft;
    С литеры i начинаются только члены класса, 
    не соблюдаете соглашение об именовании
    TInt iErr,iCount;
    TFileName sFullFileName;
    
    Не обязательно переменные стаскивать в одну кучу, это же не паскаль
    
    
    TextPoint.iX = 20;
    TextPoint.iY = 30;
    
    _LIT(KDefaultDirCName,"C:\\test.txt");
    CAknFileNamePromptDialog* NameDlg = CAknFileNamePromptDialog::NewL();
    NameDlg->SetTitleL(_L("Enter Your Name:"));
    NameDlg->SetRightSoftkeyL(_L("Cancel"));
    NameDlg->SetLeftSoftkeyL(_L("Save"));
    _LIT(KUserName,"No Name");
    
    sName.Zero(); -бессмысленно
    DialogResult = NameDlg->ExecuteL(sName);
    утечка памяти, NameDlg не уничтожен (это же ExecuteL, а не ExecuteLD)
    
    if (sName.Length()>12)
    {
    sName = sName.Mid(0,12);
    }
    
    sHeroesName.Zero(); -бессмысленно
    sHeroesName.Copy(sName);
    
    if (sHeroesName.Length()>12)
    {
    sHeroesName = sHeroesName.Mid(0,12);
    } -бессмысленно
    // Первый вывод
    iBgc->DrawText(sHeroesName, TextPoint);
    
    
    User::LeaveIfError(fsSession.Connect());
    CleanupStackPushL(fsSession);
    iErr = Ft.Replace(fsSession,KDefaultDirCName,EFileWrite);
    CleanupStackPushL(Ft);
    if(iErr == KErrNone)
    {
    sName1.Zero();
    -Вот здесь происходит копирование из TBuf16 содержащего 2-х байтовые
     символы в TBuf8, содержащий однобыйтовые. Как это происходит? 
    Да просто отбрасывается 1 байт в каждом символе.
     Для латиницы это ничего так как там один байт нулевой,
     остальные языки карёжит.
    sName1.Copy(sHeroesName);
    User::LeaveIfError(Ft.Write(sName1));
    User::LeaveIfError(Ft.Flush()); // Commit data
    
    CleanupStack::PopAndDestroy();//Ft -закрываем файл
    Это не нужно, файл закрыт, сессию оставляем открытой
    Ft.Close();
    fsSession.Close();
    
    }
    
    //не нужно
    fsSession.Connect();
    iErr = Ft.Open(fsSession,KDefaultDirCName,EFileRead);
    CleanupStackPushL(Ft);
    
    Ft.Size(iCount);
    User::LeaveIfError(Ft.Read(sT,iCount)); вот здесь бы iCount = 12,
     или хотя бы 20
    User::LeaveIfError(Ft.Flush()); // Commit data Не нужен flush,
     вы ничего не пишете, только читаете
    
    CleanupStack::PopAndDestroy(2);//Закрываем файл и сессию
    не нужно:
    Ft.Close();
    fsSession.Close();
    
    TextPoint.iY += 30;
    
    sHeroesName.Zero(); -бессмысленно
    sHeroesName.Copy(sT);
    
    if (sHeroesName.Length()>12)
    {
    sHeroesName = sHeroesName.Mid(0,12);
    }
    // второй вывод
    iBgc->DrawText(sHeroesName, TextPoint);
    
    
    }
    Reply With Quote
    Читаем FAQ по дескрипторам и Советы по дескрипторам в wiki.

    Что делать? Либо писать данные TBuf16 в файл с помощью TFileText и отказаться от работы с TBuf8 вообще. Либо по-человечески выполнять конверсию содержимого TBuf16 в ASCII и копировать полученное в TBuf8

  7. #7
    Registered User
    Join Date
    Nov 2008
    Posts
    94

    Re: Запись в файл русских символов

    Доброе утро

    Truf, большое спасибо Вам за посылание меня к документации. Благодаря Вам и документации научился читать и писать в файл, на телефоне, не только английские но и русские буквы.
    Но остался еще один вопрос связанный с выводом на экран русских букв для симулятора.
    На симуляторе ниже приведенная ф-ция выдает "арабскую вязь" и на третьем и на пятом паке. Что Вы можете еще посоветовать по этому поводу?


    void CTestGridControl::Controller()
    {

    TBool DialogResult;
    TBuf16<20> sName,sReadName;
    TPoint TextPoint;
    TInt iErr;

    TextPoint.iX = 20;
    TextPoint.iY = 30;

    _LIT(KDefaultDirCName,"C:\\test.txt");
    _LIT(KUserName,"No Name");

    CAknFileNamePromptDialog* NameDlg = CAknFileNamePromptDialog::NewL();
    NameDlg->SetTitleL(_L("Enter Your Champion Name:"));
    NameDlg->SetRightSoftkeyL(_L("Cancel"));
    NameDlg->SetLeftSoftkeyL(_L("Save"));

    DialogResult = NameDlg->ExecuteL(sName);
    if (!DialogResult)
    {
    sName.Copy(KUserName);
    }
    delete NameDlg;

    if (sName.Length()>12)
    {
    sName = sName.Mid(0,12);
    }

    iBgc->DrawText(sName, TextPoint);

    RFs fsSession;
    RFile Ft;
    TFileText text;

    User::LeaveIfError(fsSession.Connect());
    iErr = Ft.Replace(fsSession,KDefaultDirCName,EFileShareExclusive|EFileWrite);
    if(iErr == KErrNone)
    {
    text.Set(Ft);
    text.Write(sName);
    }
    Ft.Close();

    iErr = Ft.Open(fsSession,KDefaultDirCName,EFileRead);
    if(iErr == KErrNone)
    {
    text.Set(Ft);
    text.Read(sReadName);
    }
    Ft.Close();

    TextPoint.iY += 30;

    iBgc->DrawText(sReadName, TextPoint);

    fsSession.Close();

  8. #8
    Regular Contributor
    Join Date
    Sep 2003
    Posts
    134

    Re: Запись в файл русских символов

    Если прекратите обзывать Эмулятор - симулятором, подскажу .
    Возможно все дело в том, что перед iBgc->DrawText(sName, TextPoint); гдето в глубинах кода,
    спрятано iBgc->UseFont(lalala). A вот lalala не умеет писать русскими буковками. Читать документацию по шрифтам (копировать arial.ttf c:\system\font )

Similar Threads

  1. проиграть звуковой файл вместо голоса
    By kevin_kaspersky in forum Russian Developer Forum - Форум Российских разработчиков
    Replies: 10
    Last Post: 2010-12-08, 20:24
  2. CImageDecoder и bmp файл
    By ssealien in forum Russian Developer Forum - Форум Российских разработчиков
    Replies: 6
    Last Post: 2008-10-19, 15:06
  3. Эмулятор и файл с данными
    By midday in forum Russian Developer Forum - Форум Российских разработчиков
    Replies: 2
    Last Post: 2008-01-10, 11:08

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •