Предложение по доработке функции DoubleToStr

 

Функция DoubleToStr преобразует число в строку вида "1.2345". Когда мне нужно, чтобы вместо разделительной точки была запятая, использую функцию, позаимствованную в паскалевской (PASCAL) библиотеке клипперовских (CLIPPER) функций:

//+----------------------------------------------------------------------------+
//|  Замена подстроки                                                          |
//|  Параметры:                                                                |
//|    str     - текстовая строка, в которой производится замена               |
//|    strfrom - заменяемая подстрока                                          |
//|    strto   - заменяющая подстрока                                          |
//+----------------------------------------------------------------------------+
string StrTran(string str, string strfrom, string strto) {
  int    n;
  string outstr="", tempstr;
 
  for (n=0; n<StringLen(str); n++) {
    tempstr=StringSubstr(str, n, StringLen(strfrom));
    if (tempstr==strfrom) {
      outstr=outstr+strto;
      n=n+StringLen(strfrom)-1;
    } else outstr=outstr+StringSubstr(str, n, 1);
  }
  return(outstr);
}

Пример использования функции StrTran:

int start() {
  double d=1.2345;
  string s;
 
  s=DoubleToStr(d, 4);
  s=StrTran(s, ".", ",");
  Comment(s);
}

И я считал такое положение вещей нормальным до тех пор пока не обнаружил, что аналогичная функция FloatToStr в Borland Delphi 6 является чувствительной к системным установкам. Это означает, что, если в настройках операционной системы разделителем целой и дробной частей числа является запятая, то функция FloatToStr вернёт строку вида "1,2345". А если в системе разделителем является точка, то - "1.2345". В прицепе исходники Delphi и экзешник для проверки функции FloatToStr. В проекте использован компонент TRxSpinEdit для ввода числа. Перед изменением разделителя в настройках операционной системы тестовую прогу рекомендуется перегрузить, иначе вываливается с ошибкой.

Предлагаю разработчикам рассмотреть возможность доработки функции DoubleToStr и сделать её чувствительной к системным настройкам.

Файлы:
floattostr.zip  211 kb
 
Протестую. Только не это!!!!!!!!!!!
 
Integer:
Протестую. Только не это!!!!!!!!!!!
Наверно, нужно обосновать протест :-)
И хочу заметить, что мне самому доработка не нужна. Просто я увидел в этом некий стандарт и озвучил его. Подозреваю, что в Borland C++ есть функция типа FloatToStr и работает она аналогично дельфийской.
 
Пожалуй во всех языках есть зависимость от системных настроек.  Аргументов у меня нету, будем сичтать это эмоциями, хочется точку всегда видеть точкой, а зяпятую запятой и при написании программы не думать о том, какие системные настройки будут у пользователя программы. Существует можество программ теханализа, которые работают только с какими-то определенными системными настройками. Конечно это можно считать низкой квалификацией программистов, но факт, что это создает проблемы.
 
Проверил в Borland C++ 4.0 функцию FloatToStr. Так и есть... она тоже чувствительна типу системного разделителя целой и дробной частей числа. Вот тестовые скриншоты:






Прикрепляю тестовый проект Borland C++ 4.0
Файлы:
 

А как быть с уже готовыми программами? придется их переписывать? - тоесть делать проверку на текущие настройки. Например в excel по умолчанию точка является разделителем даты а запятая разделителем чисел соответственно при записи csv файла вы ориентируетесь на настройки по умолчанию.

 
Можно оставить функцию DoubleToStr() как есть и добавить ещё одну версию этой функции, которая чувсвтительна в системному разделителю, только назвать назвать по-другому, к примеру DoubleToStrF(). Да и все. Кто хочет юзает, кто не хочет -нет. :)
 
xeon:

А как быть с уже готовыми программами? придется их переписывать? - тоесть делать проверку на текущие настройки.

А почему бы и нет? Я, например, в Delphi использую контанту DECIMALSEPARATOR, которая хранит системный разделитель целой и дробной частей числа. Вот пример кода:
if DECIMALSEPARATOR='.' then s:=StrTran(s, ',', '.');
art[i].Rate1:=StrToFloat(s);
Такая проверка и преобразование позволяет мне быть всегда в "формате".

xeon:

Например в excel по умолчанию точка является разделителем даты а запятая разделителем чисел соответственно при записи csv файла вы ориентируетесь на настройки по умолчанию.

Ваше утверждение голословно. Я же точно знаю, что MS Excel использует системные установки формата даты и числа, поэтому у меня нет проблем при записи CSV-файлов. Не поленитесь и Вы это проверить. Последовательность предлагаю такую:
1. Открыть MS Excel
2. Заполнить одну ячейку значением в формате дата и вторую значением в формате число.
3. Открыть из панели управления настройки региональных стандартов.
4. Изменить разделитель даты и применить изменения. Убедиться, что MS Excel мгновенно отреагировал на такое системное изменение.
5. Аналогично с числом.
 
KimIV:
Ваше утверждение голословно. Я же точно знаю, что MS Excel использует системные установки формата даты и числа, поэтому у меня нет проблем при записи CSV-файлов. Не поленитесь и Вы это проверить. Последовательность предлагаю такую:
1. Открыть MS Excel
2. Заполнить одну ячейку значением в формате дата и вторую значением в формате число.
3. Открыть из панели управления настройки региональных стандартов.
4. Изменить разделитель даты и применить изменения. Убедиться, что MS Excel мгновенно отреагировал на такое системное изменение.
5. Аналогично с числом.

я же сказал по умолчанию .... вы же не будете каждому клиенту обяснять что перед использованием вашей программы нужно :

3. Открыть из панели управления настройки региональных стандартов.
4. Изменить разделитель даты и применить изменения. Убедиться, что MS Excel мгновенно отреагировал на такое системное изменение.
5. Аналогично с числом.


 
Luptator:
Можно оставить функцию DoubleToStr() как есть и добавить ещё одну версию этой функции, которая чувсвтительна в системному разделителю, только назвать назвать по-другому, к примеру DoubleToStrF(). Да и все. Кто хочет юзает, кто не хочет -нет.:)

Пожалуй, это самое дельное предложение. Не ломать совместимость существующего кода, а если уже правда надо, сделать новую функцию DoubleToStrRegional (или условно DoubleToStrLocalization) с указанным функционалом.

Кстати, я не видел в MQL (может, плохо искал) функции или константы-аналога DECIMALSEPARATOR в Delphi (в MS.NET это свойство NumberFormatInfo.NumberDecimalSeparator), т.е. узнать текущий системный разделитель нельзя, или я не прав?

Кстати, в MS T-SQL точка - всегда точка, независимо от погоды. Т.е. бывает по-разному.
 
У нас в MQL4 точка всегда как разделитель. Вводить региональный разделитель - это раскладывание граблей :)
Причина обращения: