Помощь - Поиск - Пользователи - Календарь
Полная версия: Строки в С++
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ада и другие языки
Nike0
Доброго времени суток, есть такой вопрос: сделал задачу, в условии было сказано "слова разделены пробелами и запятыми", для первой и третьей процедуры сделал класс делимремувер, т.к. текст вводится через гетлайн, для второй(сортировка строки по возрастанию длины слов) использовал while и вектор для сортировки, можете исправить так, чтобы во второй задаче сортировка игнорировала запятую и читала "чистое" слово?
#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
#include <algorithm>
#include <iterator>
#include <conio.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#pragma argsused

using namespace std;

class DelimRemover {
string m_sDelim;
public:
DelimRemover(const string & delim) : m_sDelim(delim) {}
string & operator () (string & s)
{
size_t pos;
while ( ( pos = s.find_first_of(m_sDelim) ) != string::npos )
s.erase(pos, 1);
return s;
}
};

bool compare(const string &a, const string &b)
{
return a.length()<b.length();
}

void q()
{
DelimRemover dr(",");
int kol = 0;
cout<<"Vvedite stroky: ";
string s;
cin.ignore();
getline(cin,s);
cout<< dr(s) << endl;
//дополним строку остальными гласными
string glasnye("eyuioa");
//инициализируем поток ввода из которого будем извлекать слова
istringstream iss(s);
cout<<"Slova, zakanchivayuschiesya na glasnuyu bukvu:"<<endl;
while (iss>>s)
if (string::npos != glasnye.find(*s.rbegin())) //poslednyaya bukva ne glasnaya?
{
cout << s << " ";
kol++;
}
cout<<endl<<"Koli4estvo slov, zakan4ivayuschihsya na glasnyu bukvu: "<<' '<<kol<<endl<<endl;
}

void w()
{
cout<<"Vvedite stroky: ";
string s;
vector<string>a;
while (cin>>s && s!="sort")
{
a.push_back(s);
}
sort(a.begin(),a.end(),compare);
copy(a.begin(),a.end(),ostream_iterator<string>(cout<<"Sortirovka "," "));
cout<<endl;
}

void e()
{
DelimRemover dr(",");
string s;
int k=0;
cout << "Vvedite stroku: ";
cin.ignore();
getline(cin, s);
cout<<endl<<dr(s)<<endl;
istringstream ist(s);
ostringstream ost;
while ( ist >> s )
if ( s.find('t') == string::npos )
{
ost << s << ' ';
k++;
}
if (k!=0)
cout << endl << "New string: " << ost.str() << endl << endl;
else
cout<<endl<<"V stroke ne ostalos' slov!"<<endl<<endl;
}

int main()
{
int b;
while (true)
{
cout<<"Vyberite zadanie: "<<endl<<"1 - Koli4estvo slov, zakan4ivayuschihsya na glasnyu bukvu. \n2 - Sortirovat stroku po vozrastaniyu. \n3 - Isklyuchit iz stroki slova< soderzhaswie bukvu t, ostavshiisya tekst vyvesti na ekran. \n0 - Exit."<<endl;
cin>>b;
switch (b)
{
case 1:{q(); break;}
case 2:{w(); break;}
case 3:{e(); break;}
case 0:{return 0;}
default: cout<<"Vy vveli nevernye dannye!";
}
}
getch();
return 0;
}



Добавлено через 4 мин.
так же появился вопрос про строки на чистом Си: мне нужно описать функцию replace(s,s1,s2), проще говоря контекстная замена текста, так вот, набросал код, но у меня что-то не очень хорошо меняет лдя случая когда искомая часть текста=заменяемой (берет непонятные значения из памяти), и вообще зацикливается, когда искомая больше-меньше заменяемой.
#include <stdio.h>
#pragma hdrstop
#include <conio.h>
#include <tchar.h>
#include <string.h>
#define N 80
#pragma argsused

int main()
{
char s[N],s1[N],s2[N];
int n;
clrscr();
printf("Vvedite stroku s:\n");
gets(s);
printf("\nVvedite stroku s1:\n");
gets(s1);
printf("\nVvedite stroku s2:\n");
gets(s2);
for (n = 0; s[n] != '\0'; n++)
{
int i;
for (i=0; s[n+i] !='\0' && s1[i] !='\0'; i++)
if (s[n+i] != s1[i])
break;
if (s1[n+i]=='\0')
{
int l2,dd,k;
l2 = strlen(s2);
dd = l2 - strlen(s1);
if (dd != 0)
{
if (dd < 0)
{
for (k=n; s[k+dd]!='\0'; k++)
s[k] = s[k+dd];
s[k]='\0';
}
else
{
for (k=n; s[k]!='\0'; k++)
for (; k != n; k--)
s[k+dd] = s[k];

}
}
for (k = 0; k < l2; k++)
s[n+k] = s2[k];
}
}
printf("%s",s);
getch();
return 0;
}
volvo
Цитата
в условии было сказано "слова разделены пробелами и запятыми"
"Пробелами и запятыми", или "пробелами или запятыми"? То есть, там, где есть запятая, ОБЯЗАТЕЛЬНО есть пробел, или может быть, а может - нет?

Если первое - то читай, как читаешь, но перед занесением в вектор удаляй запятую из строки. Если второе - то выбора у тебя нет, кроме как читать через getline всю строку, и потом ее разбирать на слова.
Nike0
Цитата(volvo @ 12.12.2010 14:21) *

"Пробелами и запятыми", или "пробелами или запятыми"? То есть, там, где есть запятая, ОБЯЗАТЕЛЬНО есть пробел, или может быть, а может - нет?

Если первое - то читай, как читаешь, но перед занесением в вектор удаляй запятую из строки. Если второе - то выбора у тебя нет, кроме как читать через getline всю строку, и потом ее разбирать на слова.

в условиии пробелами и запятыми, спасибо за подсказку, я это сделал, а что насчет 2го задания можете посоветовать?
volvo
Ошибочка у тебя, насколько я вижу:
		for (i=0; s[n+i] !='\0' && s1[i] !='\0'; i++)
if (s[n+i] != s1[i])
break;
if (s1[n+i]=='\0') /* <--- Вот тут логично было бы написать s1[ i ] */
{
Nike0
Цитата(volvo @ 12.12.2010 16:52) *

Ошибочка у тебя, насколько я вижу:
		for (i=0; s[n+i] !='\0' && s1[i] !='\0'; i++)
if (s[n+i] != s1[i])
break;
if (s1[n+i]=='\0') /* <--- Вот тут логично было бы написать s1[ i ] */
{


о, спасибо большое, вот откуда брались неверные значения из памяти, однако это решило проблему только для случаев, когда искомая подстрока = заменяемой и когда искомая < заменяемой, но вот для этого участка кода
if (dd < 0)
{
for (k=n; s[k+dd]!='\0'; k++)
s[k] = s[k+dd];
s[k]='\0';
}

очень все плохо, зацикливается и я не знаю что делать
volvo
Nike0, это вообще чей алгоритм? Голову отрывать за такие ошибки надо: насколько я вижу, dd < 0 - это признак того, что искомая строка длиннее той, на которую надо заменить. И надо "хвост" сдвинуть влево. Но, блин, ведь если dd < 0, то s[k+dd] будет левее s[k], надо либо брать |dd|, либо просто:
for (k=n; s[k-dd]!='\0'; k++)
s[k] = s[k-dd];
, тогда действительно "хвост" будет подтягиваться влево...
Nike0
Цитата(volvo @ 13.12.2010 11:19) *

Nike0, это вообще чей алгоритм?

друг помогал со сдвигом smile.gif
однако же спасибо большое, разобрался с этой штукой, теперь думаю с указателями несложно будет сделать, можно тему закрывать
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.