C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
перевернуть слова
BlastOff
Отправлено: 24.05.2004, 13:57


Не зарегистрирован







Из RichEdit'a в буфер я считываю текст. Там слова, они разделены пробелами (от одного пробела до нескольких). А надо перевернуть слова. Желательно с использованием того же буфера. Вот никак не могу сообразить как это сделать.
(Пример: abc de fgh => cba ed hgf)
AVC
Отправлено: 24.05.2004, 14:41


Ветеран

Группа: Модератор
Сообщений: 1583



А зачем с тот же буфер? Тогда переворачивать слова на этапе считывания из RichEdit
Guest
Отправлено: 24.05.2004, 15:21


Не зарегистрирован







Буфер нужен для использования в самой проге.
Подскажи, как переворачивать их на этапе считывания?
AVC
Отправлено: 24.05.2004, 15:29


Ветеран

Группа: Модератор
Сообщений: 1583



Например так:
CODE

Memo1->Lines->Text = ""; // debug
AnsiString istr;
AnsiString ostr;
char *icp, *ocp;
for (int i=0; i < RichEdit1->Lines->Count; i++)
{ istr = pRich->Lines->Strings[i].Trim();
   if (istr.IsEmpty()) continue;
   ostr = AnsiString::StringOfChar(' ', istr.Length());
   icp = istr.c_str();
   ocp = ostr.c_str() + istr.Length();
   while(*icp)  *--ocp = *icp++;

   Memo1->Lines->Add(ostr); // debug
}
BlastOff
Отправлено: 24.05.2004, 17:24


Ученик-кочегар

Группа: Участник
Сообщений: 8



Не, как перевернуть всю строку я знаю (strrev). А вот отдельные слова... Видишь, в моём примере слова остались на своих местах, поменялись лишь буквы в них.
Я просто в Си не очень шарю, не могу компактно написать эту фигню.
sad.gif
full_lamer
Отправлено: 25.05.2004, 08:48


Машинист паровоза

Группа: Участник
Сообщений: 225



Ну в чем проблема — здесь не нужно знать особо С, просто нужно знать как это делается:

0. выделяешь слово, читаешь символы от пробела, до пробела;
1. переворачиваешь его;
2. и вставляешь в буфер...

увсе..
AVC
Отправлено: 25.05.2004, 08:54


Ветеран

Группа: Модератор
Сообщений: 1583



Вообще то проблемку "как найти группу символов, ограниченную пробелом" я оставил для домашнего задания. Вот один из вариантов:
CODE

AnsiString istr, ostr, str;
int   p0, ilen;
ostr = "";
for (int i=0; i < RichEdit1->Lines->Count; i++)
{  istr = pRich->Lines->Strings[i].Trim();
   if (istr.IsEmpty()) continue;
   istr += " ";
   for (int j=1, p0=1, ilen=istr.Length(); j <= ilen; j++)
    {  if(istr[j] != ' ') continue;
       if (j <= p0)       continue;
       str = istr.SubString(p0, j-p0);
       p0 = j + 1;
       int sl = str.Length();
       char c;
       char *cp = str.c_str();
       for (int k=0; k < (sl/2); k++)
        { c = *(cp+k);
          *(cp+k) = *(cp+sl-k-1);
          *(cp+sl-k-1) = c;
        }
       ostr += "<" + str + "> ";
    } // одна строка
   ostr += "\r\n";
} // все строки
Memo1->Lines->Text = ostr; // debug
Gedeon
Отправлено: 25.05.2004, 09:27


Ветеран

Группа: Модератор
Сообщений: 1742



CODE

TStringList *SL = new TStringList();
for(int Rows=0;Rows<Memo1->Lines->Count;Rows++){
SL->Add("");
Memo1->Lines->Strings[Rows].Trim();
if(Memo1->Lines->Strings[Rows].IsEmpty()) continue;
bool EndRow;
EndRow=false;
int SpaceNum;
char *word;
while(!EndRow){
SpaceNum = Memo1->Lines->Strings[Rows].AnsiPos(" ");
if(!SpaceNum){
SpaceNum = Memo1->Lines->Strings[Rows].Length();
word = Memo1->Lines->Strings[Rows].SubString(1,SpaceNum).c_str();
EndRow=true;
}
else{
word = Memo1->Lines->Strings[Rows].SubString(1,SpaceNum-1).c_str();
}
Memo1->Lines->Strings[Rows] = Memo1->Lines->Strings[Rows].Delete(1,SpaceNum);
SL->Strings[Rows] = SL->Strings[Rows] + strrev(word);
if(!EndRow) SL->Strings[Rows] = SL->Strings[Rows] + " ";
}
}
Memo1->Clear();
Memo1->Lines = SL;
delete SL;

Это для Memo, для RichEdit то же самое только поменяйте Memo1 на RichEdit1.

Отредактировано Gedeon — 25/05/2004, 10:30
AVC
Отправлено: 25.05.2004, 10:13


Ветеран

Группа: Модератор
Сообщений: 1583



Gedeon, при использвании вашего алгоритма два раза подряд я не получаю исходный текст

До
Introduction
New members to our team
New Budget discussion
Facilities
Q & A

Suggested Topics:


Parking lot repair
Cost overruns


После
Introduction
New members   team
New Budget discussion
Facilities
Q & A

Suggested Topi


ark  repair
ost overruns

В моем решении строку
{ istr = pRich->Lines->Strings[i].Trim();
заменить на
{ istr = RichEdit1->Lines->Strings[i].Trim();
осталось от отладки
Gedeon
Отправлено: 25.05.2004, 10:53


Ветеран

Группа: Модератор
Сообщений: 1742



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

Отредактировано Gedeon — 25/05/2004, 12:00
xTrim
Отправлено: 25.05.2004, 11:31


Машинист паровоза

Группа: Участник
Сообщений: 208



так подойдет?
CODE

for (int i=0; i < RichEdit1->Lines->Count; i++)
{
 AnsiString in = RichEdit1->Lines->Strings[i]+" ";
 AnsiString out = "";
 while(int p = in.Pos(" "))
 {
  for(int j=p-1;j!=0;j--) out += in[j];
  out += in[p];
  in = in.SubString(p+1,in.Length());
 }
 out = out.SubString(1,out.Length()-1);
 RichEdit1->Lines->Strings[i] = out;
}
Gedeon
Отправлено: 25.05.2004, 11:46


Ветеран

Группа: Модератор
Сообщений: 1742



Свой вариант пофиксил можно так:
CODE

TStringList *SL = new TStringList();
for(int Rows=0;Rows<Memo1->Lines->Count;Rows++){
SL->Add("");
Memo1->Lines->Strings[Rows].Trim();
if(Memo1->Lines->Strings[Rows].IsEmpty()) continue;
bool EndRow;
EndRow=false;
int SpaceNum;

while(!EndRow){
char word[300];
SpaceNum = Memo1->Lines->Strings[Rows].AnsiPos(" ");
if(!SpaceNum){
SpaceNum = Memo1->Lines->Strings[Rows].Length();
strcpy(word , Memo1->Lines->Strings[Rows].SubString(1,SpaceNum).c_str());
EndRow=true;
}
else{
strcpy(word , Memo1->Lines->Strings[Rows].SubString(1,SpaceNum-1).c_str());
}
Memo1->Lines->Strings[Rows] = Memo1->Lines->Strings[Rows].Delete(1,SpaceNum);
SL->Strings[Rows] = SL->Strings[Rows] + strrev(word);
if(!EndRow) SL->Strings[Rows] = SL->Strings[Rows] + " ";
}
}
Memo1->Clear();
Memo1->Lines = SL;
delete SL;

или так
CODE

TStringList *SL = new TStringList();
for(int Rows=0;Rows<Memo1->Lines->Count;Rows++){
SL->Add("");
Memo1->Lines->Strings[Rows].Trim();
if(Memo1->Lines->Strings[Rows].IsEmpty()) continue;
bool EndRow;
EndRow=false;
int SpaceNum;
String word;
while(!EndRow){
SpaceNum = Memo1->Lines->Strings[Rows].AnsiPos(" ");
if(!SpaceNum){
SpaceNum = Memo1->Lines->Strings[Rows].Length();
word = Memo1->Lines->Strings[Rows].SubString(1,SpaceNum).c_str();
EndRow=true;
}
else{
word = Memo1->Lines->Strings[Rows].SubString(1,SpaceNum-1).c_str();
}
Memo1->Lines->Strings[Rows] = Memo1->Lines->Strings[Rows].Delete(1,SpaceNum);
SL->Strings[Rows] = SL->Strings[Rows] + strrev(word.c_str());
if(!EndRow) SL->Strings[Rows] = SL->Strings[Rows] + " ";
}
}
Memo1->Clear();
Memo1->Lines = SL;
delete SL;


Отредактировано Gedeon — 25/05/2004, 12:49

Вернуться в Вопросы программирования в C++Builder