String to Double
8 отговора
307 прегледа
String to Double
Здравейте,
Имам проблем с една моя програма /Borland C++ Builder/ която се стартира на PC-та с Win2k или WinXP с ограничени права. Проблемът е, че понякога при конверсия на стринг в double се генерира изключение за грешка EConversionError, въпреки че се въвежда коректно реално число/ 2.95/. Напр. при: dTmp = Edit1->Text.ToDouble();
Предполагам, че това е заради регионалните настройки/разделителя за десетична точка/, но за жалост както вече казах, PC-тата са с ограничени права. Не знам админ паролата а и нямам никакво желание да променям настройките на клиентите.
В основният cpp файл имам следните редове:
Application->UpdateFormatSettings = false;
DecimalSeparator = '.';
Application->UpdateFormatSettings = true;
Application->Run();
Горните редове би трябвало да решават проблема, но въпреки това програмата ми генерира EConversionError от време на време. Един от възможните варианти е да използвам strtod() от C runtime library, но тя не генерира изключения и трябва да проверявам всеки път върнатата ст-ст.
Защо Борланд са направили стринговите конверсии зависими от регионалните настройки ?!!!?
Бих се радвал да чуя вашето мнение по въпроса.
Имам проблем с една моя програма /Borland C++ Builder/ която се стартира на PC-та с Win2k или WinXP с ограничени права. Проблемът е, че понякога при конверсия на стринг в double се генерира изключение за грешка EConversionError, въпреки че се въвежда коректно реално число/ 2.95/. Напр. при: dTmp = Edit1->Text.ToDouble();
Предполагам, че това е заради регионалните настройки/разделителя за десетична точка/, но за жалост както вече казах, PC-тата са с ограничени права. Не знам админ паролата а и нямам никакво желание да променям настройките на клиентите.
В основният cpp файл имам следните редове:
Application->UpdateFormatSettings = false;
DecimalSeparator = '.';
Application->UpdateFormatSettings = true;
Application->Run();
Горните редове би трябвало да решават проблема, но въпреки това програмата ми генерира EConversionError от време на време. Един от възможните варианти е да използвам strtod() от C runtime library, но тя не генерира изключения и трябва да проверявам всеки път върнатата ст-ст.
Защо Борланд са направили стринговите конверсии зависими от регионалните настройки ?!!!?
Бих се радвал да чуя вашето мнение по въпроса.
Re: String to Double
> Защо Борланд са направили стринговите конверсии зависими от регионалните настройки ?!!!?
Ами защото, ако беше обратното, доста повече хора щяха да изпищят.
Ако грешката се получава "от време, на време", а не всеки път при дадените условия (еднакви числа и т.н.), явно проблема е някъде в твоя код - виж си логиката, правилно ли заделяш и освобождаваш динамичните ресурси (обекти, масиви и пр.), включи си опциите за проверки на компилатора и пусни един debug на реална клиентска машина (най-добре) или го симулирай при теб с ограничен акаунт.
Варианта с конверсия без изключения остава, но той е заобикаляне, а не решение на проблема.
Mixy
Ами защото, ако беше обратното, доста повече хора щяха да изпищят.
Ако грешката се получава "от време, на време", а не всеки път при дадените условия (еднакви числа и т.н.), явно проблема е някъде в твоя код - виж си логиката, правилно ли заделяш и освобождаваш динамичните ресурси (обекти, масиви и пр.), включи си опциите за проверки на компилатора и пусни един debug на реална клиентска машина (най-добре) или го симулирай при теб с ограничен акаунт.
Варианта с конверсия без изключения остава, но той е заобикаляне, а не решение на проблема.
Mixy
Re: String to Double
Лошото е, че грешката се появява от време на време. Няма омазани указатели, защото в конкретната форма използвам STL vector и няма съобщение от Code Guard за неосвободени ресурси. Мисля да дебъгвам с remote debuger-a, ако изчерпя др. варианти.
Нямам представа как е в Делфито, но за С/С++ Builder-a Edit1->Text.ToDouble() определено не ми харесва. C Runtime library и STL (или поне STLport) не признават запетаята като разделител м/у цялата и дробната част.
Нямам представа как е в Делфито, но за С/С++ Builder-a Edit1->Text.ToDouble() определено не ми харесва. C Runtime library и STL (или поне STLport) не признават запетаята като разделител м/у цялата и дробната част.
Re: String to Double
Аз съм "делфист" и Ц/Ц++ не съм много ... ама все пак.
Нещо не разбрах докрай...
UpdateFormatSetting - защо ти е да го ползваш?
ако числото се въвежда от потребителя в Edit контрол,
то най-логичното е да се ползват регионалните настройки.
А ако държиш винаги да е точка разделителя, то
DecimalSeparator = '.' е достатъчно.
А EConversionError ти трябва така или иначе да си го обработваш,
нали потребителя пише в този Edit?
Ами ако напише глупост, някакви букви а не число, то тогава?
ако правелно съм схванал същността , то не ти трябва да пипаш
никакви настройки , ще се ползват регионалните,
а ако потребителя напише глупост то ще реагираш
по начин подходящ за ситуацията. Естествено е
да прихванеш изключението и да кажеш нещо от
сорта - "Грешно въведено число" и той да го пише пак.
Нещо не разбрах докрай...
UpdateFormatSetting - защо ти е да го ползваш?
ако числото се въвежда от потребителя в Edit контрол,
то най-логичното е да се ползват регионалните настройки.
А ако държиш винаги да е точка разделителя, то
DecimalSeparator = '.' е достатъчно.
А EConversionError ти трябва така или иначе да си го обработваш,
нали потребителя пише в този Edit?
Ами ако напише глупост, някакви букви а не число, то тогава?
ако правелно съм схванал същността , то не ти трябва да пипаш
никакви настройки , ще се ползват регионалните,
а ако потребителя напише глупост то ще реагираш
по начин подходящ за ситуацията. Естествено е
да прихванеш изключението и да кажеш нещо от
сорта - "Грешно въведено число" и той да го пише пак.
Re: String to Double
Успях да хвана грешката. Проблема идваше при получаване и конвертиране на текста от TEdit поле в double от сървърната част, а не при въвеждане на данни във формата.
Програмата ми е от 2 части - клиент и сървърна част, които си комуникират с Indy сокети и трябва да съгласувам форматите на 2-та компютъра. Затова използвам DecimalSeparator = '.'
А колкото до UpdateFormatSetting трябва да остане само реда
Application->UpdateFormatSettings = false; за да не може клиента да промени регионалните настройки на разделителя м/у цяла и дробна част, докато програмата е активна. Или по скоро за да не се отрази това на активната програма
- параноя в чист вид.
Реда Application->UpdateFormatSettings = true; е излишен.
Програмата ми е от 2 части - клиент и сървърна част, които си комуникират с Indy сокети и трябва да съгласувам форматите на 2-та компютъра. Затова използвам DecimalSeparator = '.'
А колкото до UpdateFormatSetting трябва да остане само реда
Application->UpdateFormatSettings = false; за да не може клиента да промени регионалните настройки на разделителя м/у цяла и дробна част, докато програмата е активна. Или по скоро за да не се отрази това на активната програма
Реда Application->UpdateFormatSettings = true; е излишен.
Re: String to Double
Спомням си как веднъж в малка непретенциозна програмка ползвах нещо от сорта :
Работеше безотказно.
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Edit1->OnKeyPress = FixCommaIssue ;
Edit2->OnKeyPress = FixCommaIssue ;
Edit3........
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FixCommaIssue(TObject *Sender, char &Key)
{
char *dec = StrAlloc(10) ;
GetLocaleInfo(
LOCALE_SYSTEM_DEFAULT,
LOCALE_SDECIMAL,
dec,
10);
if(Key==44||Key==46)Key=*dec ;
}
Работеше безотказно.
Clipboard
Това нещо работи докато юзера не вземе да си пейстне от някъде числото с '.' вместо с ',' или обратно...
Re: Clipboard
Мда, прав си.
Явно съм забравил каква беше пълната процедура :)
Може би bool TryStrToFloat(...) ; също би била полезна в подобни случаи.
Все пак няколко подхода към един проблем никога не са излишни.
Явно съм забравил каква беше пълната процедура :)
Може би bool TryStrToFloat(...) ; също би била полезна в подобни случаи.
Все пак няколко подхода към един проблем никога не са излишни.
Re: Clipboard
Благодаря на всички които взеха отношение по тази тема.
Както каза Sury: Все пак няколко подхода към един проблем никога не са излишни.
Както каза Sury: Все пак няколко подхода към един проблем никога не са излишни.