Aplikacja nie dziala "w innych czesciach" swiata

0

Witajcie, mam nastepujacy problem :
Napisalem ostatnio aplilkacje w bcb korzystajacą z plikow xml(przechowywanie danych). Jakze wielkie bylo moje zdziwienie kiedy po wielu testach przeprowadzonych przez kumpli w Polsce dostalem informację, ze program niewlasciwie dziala w innych regionach swiata.

W sumie to brzmi niedorzecznie, ale program ma problemy z okresleniem sciezki do zapisywanych plikow(tak mi sie przynajmniej wydaje).

Dodam ze pliki mają rozszerzenie .xml, czy to moze byc wina kodowania?

Coz jeszcze moge dodac, u jednych userow program dziala ok(vista, xp), a u inni dostaja bledy zwiazane z zapisem danych, czy nawet bledy wynikajace z dzieleniem liczb typu float(invalid floating point value) - chodzi tu chyba o kropke i przecinek.

Problem jest ciezki do rozwiazania : /

Ma ktos jakies sensowne wytlumaczenie?

Dzieki

0

Po pierwsze - problem z liczbami zapewne wynika z kropki lub przecinka (w produktach Borlanda jest zmienna DecimalSeparator). Przed zamianą danych na float proponuję zamienić wszystkie kropki na DecimalSeparator oraz wszystkie przecinki na DecimalSeparator.

Po drugie - musiałbyś pokazać kawałek kodu, z którym ma problemy ze ścieżkami - jeśli 'inne części świata' oznaczają Azję, to najprawdopodobniej ma problem ze znakami Unicode w ścieżce. Obstawiam, że albo używasz wersji ASCII, albo wręcz komend borlandowych (reset/rewrite/seek/assignfile) co w takim przypadku może być główną przyczyną.

Ewentualnie kodowanie w samym pliku XML jest niewłaściwe (na przykład plik generowany przez inny program może mieć kodowanie niespotykane w Polsce - choćby Big5; standardowe komponenty tego najprawdopodobniej nie obsłużą).

Oba ostatnie przypadki łatwo przetestować, samemu tworząc sobie katalog lub plik z nietypową nazwą (możesz zbiór literek wziąć z Google :) ) lub nietypową treścią.

0

Po drugie - musiałbyś pokazać kawałek kodu, z którym ma problemy ze ścieżkami - jeśli 'inne części świata' oznaczają Azję, to najprawdopodobniej ma problem ze znakami Unicode w ścieżce. Obstawiam, że albo używasz wersji ASCII, albo wręcz komend borlandowych (reset/rewrite/seek/assignfile) co w takim przypadku może być główną przyczyną.

No faktycznie niektóre znaki wprowadzone np. do nazwy folderu powodują, iż program się wysypuje - nie potrafi odczytać ścieżki - to już jeden problem byłby z głowy. Tylko powiedz mi teraz Szczawiku, co musiałbym zrobić aby wprowadzić obsługę niestandardowego kodowania.

Prawdopodobnie to samo będzie z DecimalSeparator'em, bo napisałem obsługę kropek i przecinków, które są odpowiednio zamieniane przed konwertowaniem do float, ale jak widać i to jest niewłaściwie zrobione.

Piękne dzięki.

0

A tak btw jeszcze...
Jak użyć tej właściwości DecimalSeparator?
Czyżby wystarczyło tylko przy tworzeniu formy ustawić DecimalSeparator = ','; albo = '.';
A jeżeli już na co? Na kropkę czy przecinek? To będzie zależne od regionu tak? No więc jak wykryć region?

Nie wiem czy dobrze myślę, dlatego pomóż ; -)

0

Jesli chodzi o sciezki to powinny dzialac w unicode ... no i tu moze byc klops z delphi bo chyba nie uzywa.

Standardowo ma funkcje GetOpenFileNameA (zapisana jako GetOpenFileNameA) w TOpenDialog a powinna byc GetOpenFileNameW.

0

Reichel, program napisany w bcb, chociaż to też vcl, wiec bedzie chyba ten sam problem.

Swoją drogą wczesniej pytałem jak wykryc ten Separator. Czyżby w tej zmiennej zaraz po włączeniu programu pojawiał się taki znak, jaki ma dany region? I nie muszę nic "wykrywać" ?
To takie moje przypuszczenie, ale nie jestem pewien, dlatego dobrze by bylo gdyby ktoś to mógł potwierdzić bo nie mam za bardzo jak tego sprawdzic ;- )

0

Dokładnie - zmienna po uruchomieniu programu ma ustawiony systemowy separator (zależny od ustawień regionalnych). Warto przed wczytaniem zamienić kropki i przecinki na ten separator, bo system zachowa się prawidłowo zarówno dla wpisanej kropki, przecinka, jak i ewentualnego innego znaku.

0

DecimalSeparator działa jak trzeba!
Mam nadzieję, że kiedyś postawię Ci piwko, jak nie w tym, to w innym życiu ; -)

0

Co do ścieżek, pokaż przykład otwierania pliku XML (raczej dobierania się do jego otwarcia, bo co potem robisz, raczej wpływu nie ma; choć też fragmentem rzucić możesz).

0

Dzięki za zainteresowanie.
Kawałek procedury zapisującej :

TNativeXml *ADoc;
TFileStream *fp;
String FileName;
int i;

ADoc = new TNativeXml("ProgramName");
ADoc->EncodingString = "iso-8859-2";


FileName = ExtractFileDir(Application->ExeName )+ "\\opt.xml";

fp = new TFileStream(FileName, fmCreate);
TXmlNode *item, *item2;

ADoc->Root->Name = "ProgramNameOptionsFile";

ADoc->XmlFormat = xfReadable;


item = ADoc->Root->NodeNew("Main");
item2 = item->NodeNew("Other");
item2->NodeNew("cos_tam")->ValueAsInteger = Combo->ItemIndex;
item2->NodeNew("cos_tam2")->ValueAsInteger = CCType->ItemIndex; //itd...


ADoc->SaveToStream(fp);

fp->Free();
delete(ADoc);

No i odczyt

String FileName = ExtractFileDir(Application->ExeName )+ "\\opt.xml";

TFileStream *fp = new TFileStream(FileName, fmOpenRead);
char c;

TNativeXml *ADoc = new TNativeXml("ProgramName");
ADoc->EncodingString = "iso-8859-2";
 int size;
 String data;
TXmlNodeList *BList;

TXmlNode *ANode;


BList = new TXmlNodeList;

size = fp->Size;

  for(int i = 0; i<=size; i++)
  {
  fp->Read(&c,1);

  data += c;
  }
  fp->Free();

  ADoc->ReadFromString(data);

   ANode = ADoc->Root->NodeByName("Main"); // i dalej standardowy odczyt

Dopatrzyłeś się rażących nieprawidłowości?

0

Właściwie błędów jest kilka - po pierwsze FileName jest typu String, a ten nie jest w stanie przechowywać prawidłowo znaków Unicode (Application->ExeName czy ExtractFileDir też zwrócą nieprawidłową ścieżkę, jeśli plik jest w takim katalogu).

FileStream również nie możesz wykorzystać, jeśli nazwa pliku zawiera znaki Unicode (bo - znów String tego nie obsługuje). W tym wypadku proponuję samodzielnie plik otworzyć funkcjami Winapi z końcówką W (n.p.: CreateFileW), wczytać do MemoryStream, a dopiero stamtąd odczytywać. Analogicznie w drugą stronę, z MemoryStream zapisz dane do pliku funkcjami Winapi.

Kolejna sprawa to strona kodowa samego pliku XML. Jeśli samodzielnie nie zadbasz, by był w iso-8859-2 (konwertując litery), to domyślnie zapisze się z kodowaniem Windows'a (w Polsce windows-1250; w innym kraju być może inaczej). Zatem skoro i tak musisz o to ręcznie zadbać, trzymaj dane w Unicode (na przykład w UTF-8).

Podsumowując - wiem, że tym Cię nie pocieszę, ale - aby ten kod naprawdę był przenośny, musisz go przepisać od nowa.

0

Yhm.
Z kodowaniem nie ma problemu.
Z tym stringiem faktycznie jest błąd - może być zmienna TFileName - czy to coś w ogóle zmieni?
Z funkcjami API raczej nie będzie problemu.

A co z ExtractFileDir? Albo ExeName? Jak to zastąpić? ; /

0

Typ zmiennej TFileName też pochodzi od String - użycie jej nic nie zmieni.

Funkcje można zastąpić samodzielnie, pisząc na bazie ich obecnej implementacji w VCL (warto sprawdzić, bo może będą działać niektóre prawidłowo, bo separatory ścieżek w Unicode i ACSII mają takie same kody).

Co do wersji ExeName, to w Winapi masz funkcje z rodziny GetCommandLineW, CommandLineToArgvW, itp.

Pamiętaj, że po użyciu funkcji Unicodowych (zakończonych na W), program prawdopodobnie przestanie działać na Windows 9x/ME.

0

Taka uwaga:

  1. Mozna ladnie obudowac TFileStream np w klase TFileStreamW i zmienic tylko konstruktor
    otwierajacy plik z CreateFile na CreateFileW i zpaisujacy do Handle.
    albo obudowac THandleStream

  2. Unicode jest wspierany od win 95 (jesli nie ma, mozna za soba ciagnac pakiet upgrejdujacy microsoftu Unicode layer). Problem lezy tu raczej w samej funkcji CommandLineToArgvW tostepnej tylko dla NT (mozliwe, ze jest inna metoda)

0
Szczawik napisał(a)

Pamiętaj, że po użyciu funkcji Unicodowych (zakończonych na W), program prawdopodobnie przestanie działać na Windows 9x/ME.

Miałem na myśli, że mogą wystąpić inne f-cje, których na tych systemach nie uświadczysz. Poza tym większość mi znanych chodzących jeszcze Windows 9x nie ma zainstalowanej obsługi Unicode.

0

Dzięki panowie.
Mniej więcej wiem co i jak. Jakbym miał jeszcze jakieś problemy to będę uderzał.

1 użytkowników online, w tym zalogowanych: 0, gości: 1