Скачать MetaTrader 5
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Вся история MQL5.community в одном месте!
Stanislav Korotky
16374
Stanislav Korotky 2011.06.26 21:47 
Всем привет. Обнаружил баг. Имеется текст длиной (в частном случае) 7587 символа. Описан как string Text, заполняется из винды. В начале обработки там содержится то, что нужно - проверял и длину через StringLen, и выводил начало и конец через Print. Этот текст в цикле разбивается на строки по символам \r\n такой конструкцией: line = StringSubstr(ls, 0, pos); ls = StringSubstr(ls, pos + StringLen(separator)), где ls - локальная копия изначально равная Text, pos - позиция где найден сепаратор \r\n. Так вот после вызова оператора ls = ... длина текста усекается до 4095. Вывел в лог все переменные, так что могу утверждать, что "чудо" происходит именно при вызове StringSubstr, а не в mql-коде. Пробовал также явно указывать длину подстроки через третий параметр (а-ля, ls = StringSubstr(ls, pos + StringLen(separator), StringLen(ls) - pos - StringLen(separator))) - то же самое. Что за фигня? Если действительо есть проблемы с StringSubstr, расскажите плиз кто что использует взамен - наверняка есть готовые скрипты. Заранее спасибо.
Stanislav Korotky
16374
Stanislav Korotky 2011.06.26 22:09  

Дополнение. Написал в лоб для StringSubstr функцию-замену вот такую:

string StringSubstrX(string ls, int pos)
{
  string result;
  int len = StringLen(ls);
  for(int i = 0; i < len - pos + 1; i++)
  {
    result = StringConcatenate(result, CharToStr(StringGetChar(ls, pos + i)));
  }
  return(result);
}

С ней весь скрипт работает нормально, хотя и тормозит.

Rustamzhan Salidzhanov
7661
Stanislav Korotky
16374
Stanislav Korotky 2011.06.26 22:33  
И что? Документацию я читал. Там нет ни слова об ограничении длины строки (не путать с литералом). Длинное целое, зарезервированное внутри под длину строки, явно не равно 4096.
Alexey Navoykov
3957
Alexey Navoykov 2011.06.27 00:04  

Вы бы для начала привели ЦЕЛИКОМ тот кусок кода, который приводит к описанной проблеме. А то по вашему словесному описанию трудно что-то понять. Да и вообще попытка описать код словами выглядит весьма странно. Программист поймёт всё и без слов.

Я лично никаких проблем со StringSubstr не испытываю, хотя иногда использую (и получаю) там строки и по 100К.

Но судя по вашей приведённой функции-замене, я догадываюсь что в исходном коде у вас была такая же ошибка, как и в этой функции: строковая переменная ничем не проинициализирована. Инициализацию надо делать обязательно, иначе проблем не оберёшься. Обычно делают так: string result="";

Slawa
Модератор
6676
Slawa 2011.06.27 13:33  

Посмотрите код ошибки, возвращаемый GetLastError. Скорее всего это ERR_TOO_LONG_STRING (4011) - не хватает места во внутреннем буфере.

Изначально внутренний буфер распределён на 4096 символов с учётом терминирующего нуля. В некоторых случаях этот буфер может быть перераспределён автоматически. Одним из таких случаев может быть функция StringConcatenate

Попробуйте сначала получить заведомо большую строку при помощи этой функции, однократно. А уже потом попробуйте вызвать StringSubstr

Stanislav Korotky
16374
Stanislav Korotky 2011.06.27 21:30  
Meat:

Но судя по вашей приведённой функции-замене, я догадываюсь что в исходном коде у вас была такая же ошибка, как и в этой функции: строковая переменная ничем не проинициализирована. Инициализацию надо делать обязательно, иначе проблем не оберёшься. Обычно делают так: string result="";

Делал инициализацию пустой строкой - не помогло. В общем, stringo пролил свет, но пока я оставил "затычку".
. ... Rick D. ... .
1072
. ... Rick D. ... . 2011.10.03 23:59  

Наткнулся на похожую проблему.

Было:

string item = "";
item = StringSubstr(str, pos1, pos2-pos1);

При большой длине str не работало - часть текста отсекалась.

Заменил на:

string item = "";
if (pos2-pos1 >= 4096) item = str;
      
item = StringSubstr(str, pos1, pos2-pos1);
Теперь item предварительно инициализируется большой строкой и StringSubstr заработал правильно.
Алексей Тарабанов
7220
Алексей Тарабанов 2011.10.04 00:15  

Встретились два друга, один - другому: давай выпьем? - нет, мне врач запретил. Да ладно, я своему 100 баксов дал - все разрешил.

Это не оффтопик, а призыв не пользоваться строковыми переменными длинною более 256 байт :)

Mikhail Dovbakh
3556
Mikhail Dovbakh 2011.10.04 02:12  
tara:

Встретились два друга, один - другому: давай выпьем? - нет, мне врач запретил. Да ладно, я своему 100 баксов дал - все разрешил.

Это не оффтопик, а призыв не пользоваться строковыми переменными длинною более 256 байт :)

следуя Вашему методу "призывов" - не больше 128!

Надёжней!

А еще лучше не больше 64...

:)

---

Чем обоснуете, если не секрет свой "призыв"?

/
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий