2011-02-02 2 views
0

Вот моя ситуация.Поиск индекса в массиве символов заданного столбца и строки?

У меня есть алгоритм обертывания слов, который генерирует текстовые строки либо при слишком большой ширине, либо в тексте находит \ n или '-'.

Поэтому он не включает в себя '\ n' в строке текста. Это сложная часть для меня.

Я пытаюсь сделать алгоритм, который вернет индекс в массиве символов, учитывая строку и столбец.

Итак, если длина строки 1 равна 20, а длина строки 2 равна 10, если в строке 1 изначально была «\ n», она должна учитывать это.

Ex:

текст:

Hello blue sky\nworld 

мы тогда получаем 2 линии:

Hello blue sky 
world 

теперь, если мой каретка представлен '|' и я помещаю его здесь:

Hello blue sky 
    |world 

Результат не четырнадцатый характер, а скорее пятнадцатый характер, так как невидимое «\ п» должен быть учтены.

Хитрость, если слово обертывание решает произвести «\ п»

например:

Hello blue 
    sky 
    |world 

В этом случае результат должен еще быть 15 с WordWrap толкнул новую строку, но не потому, что в тексте был «\ n».

Благодаря

Here is my mess so far: 

int AguiTextBox::indexFromColumnRow(int column, int row) 
{ 
    int len = 0; 
    int charCount = 0; 
    std::string curChar; 

    int curLen = 0; 
    int bytesSkipped = 0; 
    std::string::const_iterator it = getText().begin(); 
    std::string::const_iterator end = getText().end(); 

    if(textRows.size() == 0) 
    { 
     return -1; 
    } 
    for(int i = 0; i < row; ++i) 
    { 
     len = _unicodeFunctions.getUtf8StringLength(textRows[i]); 

     for(int j = 0; j < len; ++j) 
     { 
      //skip characters that would not have passed the newline test 
      do 
      { 
       curLen = _unicodeFunctions.bringToNextUnichar(it,end); 
       curChar = getText().substr(bytesSkipped,curLen); 
       bytesSkipped += curLen; 
       charCount++; 
      } 
      while(curChar[0] < ' '); 
     } 

    } 

    len = len = _unicodeFunctions.getUtf8StringLength(textRows[row]); 


    if(column == 0 && charCount + 1 < getTextLength()) 
    { 
     curChar = _unicodeFunctions.getUtf8SubStr(getText(),charCount,1); 

     while(charCount < getTextLength() - 1) 
     { 
      if(curChar[0] < ' ' && curChar[0] != '\n') 
      { 
       charCount++; 
       curLen = _unicodeFunctions.bringToNextUnichar(it,end); 
       curChar = getText().substr(bytesSkipped,curLen); 
       bytesSkipped += curLen; 
      } 
      else 
      { 
       break; 
      } 
     } 
     if(curChar[0] == '\n') 
     { 
      charCount++; 
      curLen = _unicodeFunctions.bringToNextUnichar(it,end); 
      curChar = getText().substr(bytesSkipped,curLen); 
      bytesSkipped += curLen; 
     } 
    } 
    for (int i = 0; i < column; ++i) 
    { 
     do 
     { 
      curLen = _unicodeFunctions.bringToNextUnichar(it,end); 
      curChar = getText().substr(bytesSkipped,curLen); 
      bytesSkipped += curLen; 
      charCount++; 
     } 
     while(curChar[0] < ' '); 
    } 

    return charCount - 1; 
} 

//and the opposite 
AguiPoint AguiTextBox::columnRowFromIndex(int index) 
{ 
    std::string::const_iterator it = getText().begin(); 
    std::string::const_iterator end = getText().end(); 

    std::string curChar; 
    int charCount = 0; 
    int len = 0; 
    int byteCount = 0; 
    int curLen = 0; 
    for(int i = 0; i < (int)textRows.size(); ++i) 
    { 
     len = _unicodeFunctions.getUtf8StringLength(textRows[i]); 

     for(int j = 0; j < len; ++j) 
     { 

      //skip characters if needed 
      curLen = _unicodeFunctions.bringToNextUnichar(it,end); 
      curChar = getText().substr(byteCount,curLen); 
      byteCount += curLen; 

      while (curChar[0] < ' ' && curChar[0] != '\n') 
      { 
       curLen = _unicodeFunctions.bringToNextUnichar(it,end); 
       curChar = getText().substr(byteCount,curLen); 
       byteCount += curLen; 
      } 
      if(curChar[0] == '\n') 
      { 
       charCount++; 
       if(charCount == index) 
       { 
        return AguiPoint(j,i); 
       } 

      } 
      charCount++; 
      if(charCount == index) 
      { 
       return AguiPoint(j,i); 
      } 



     } 
    } 
    return AguiPoint(len,textRows.size() - 1); 
} 
+0

* Покажите нам свой код *. Что у вас есть до сих пор и где это происходит не так? –

+0

@ Джонатан Гринспан Я отправил свой код, но он работает не очень хорошо. – jmasterx

+0

Просто так вы знаете: если 'getText()' возвращает значение 'std :: string' по значению, вы должны его вызывать только один раз. В противном случае итераторы не будут корректно совпадать (хотя я не вижу, что вы их вообще используете.) –

ответ

0

Это мне не ясно, что именно вам нужно сделать с данными. Вы пытаетесь написать редактор или что именно?

Одна вещь, которую вы можете сделать, это построить массив указателей на начало каждой строки и, возможно, длину каждой строки.

Таким образом, вы можете представлять все строки без изменения базовых данных.

Но вы должны лучше описать требования к конвертированным данным.

+0

Я создаю TextBox, который поддерживает WordWrap, и мне нужна эта функция для удаления в позиции каретки. – jmasterx

+0

Это не для Windows, тогда, я предполагаю? Не подскажет ли мое предложение? –

Смежные вопросы