Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Вырезать из строки слова


Автор: Metalex 9.11.2009, 13:29
http://ipicture.ru/
http://ipicture.ru/
Задача 269:
http://ipicture.ru/
Ни до чего лучшего я не додумался, кроме как записывать в динамический массив номер начала и конца каждого слова, а потом уже используя этот массив с номерами, сравнивать слова. Пока я только запрограммировал запись этих  номеров еще без сравнения:
Код
#include<iostream.h>
#include<conio.h>
#include<stdio.h>  //gets
#include<string.h> //strlen

int main()
{
int i, j, elem_i=0, elem_j=0, n, number=0;

cout<<"Vvedite tseloe n - kolishestvo vashih simvolov\n";
cin>>n;

char *str;
str=new char [n+1];

gets(str);

int **word;
word=new int*[n];

for (i=0; i<(strlen(str)+1); i++)
{
    if ((str[i]==' ')||(str[i]=='\0'))
    {
        if ((str[i-1]!=' ')&(i!=0))
        {
            word[elem_i][0]=number;
            word[elem_i][1]=(i-1);
        }
        elem_i++;
    }
    else number++;
}

for (i=0; i<elem_i; i++)
for (j=0; j<2; j++)
cout<<word [i][j]<<"\n";

for (i=0; i<strlen(str); i++)
    delete word[i];

delete [] word;
delete [] str;
str=0;
word=0;

getch ();
return 0;
}

При исполнении ввод происходит нормально, а когда должены выводится номера, окно просто закрывается...(Borland C++ 3.1) Помогите найти ошибку здесь, а дальше буду пытатся сравнивать.

Автор: mekhanikus 10.11.2009, 13:04
Может стоит перейти на с++?
Вот пример из Страуструпа.
Программа считает количество повторений каждого слова.
До сабжа рукой подать.

Код

map<string,int>histogram;

void record(const string& s)
{
    histogram[s]++;
}

void print(const pair<const string,int>& r)
{
    cout << r.first << '\t' << r.second << '\n';
}

istream_iterator<string>ii(cin);
istream_iterator<string>eos;

for_each(ii,eos,record);
for_each(histogram.begin(),histogram.end(),print);

Автор: Metalex 10.11.2009, 17:45
и как она работает? мне ничего не понятно

Автор: Metalex 10.11.2009, 18:47
неужели программисты не могут найти ошибку в моем коде?

Автор: Abyx 10.11.2009, 19:43
Metalex, твой код большой, страшный и непонятный.
никто не хочет его читать
перепиши на С++

Автор: Metalex 10.11.2009, 20:35
Abyx, а это что?

Автор: N1ko 11.11.2009, 00:37
Основная проблема по которой ты даже не можешь посмотреть результаты своей программы - это особенности оператора gets. Объясняю подробнее: перед его использованием ты вводишь колличество символов оператором cin>>n; Соответственно в n записывается введённое тобой число а во входной очереди остаётся последовательность '/n', собственно на которую gets и реагирует. Таким образом gets принимает эту последовательность и завершается и в твоём чаровском масиве записывается 0 символов. А вся строкаа, которую ты пишешь дальше - ты пишешь для оператора getch(). Поставь после cin>>n; оператор getch() и будешь уже получать содержательные результаты, на которые будешь уже сстветственно реагировать.

ЗЫ А сам код не смотрел, потому что он у тебя действительно кривовато написан и нет никакого желания тратить время на его проверку. 
ЗЫЫ И перейди с (Borland C++ 3.1) на что нибуть поновее. Слишком уж старая версия плюсов. =)

Автор: Metalex 11.11.2009, 00:43
N1ko, getch() - это для задержки экрана, чтоб он не пропадал сразу же после выполнения программы. 
Посоветуй, на что поновее?

Автор: N1ko 11.11.2009, 02:02
1) getch() насколько я помню ждёт принятия одного символа, а задержка экрана это только последствие работы этого оператора
Цитата

int getch();
Описание:
Функция getch читает без эхо-отображения отдельный символ прямо с консоли

2) Ну например dev C++ А если собираешься серьёхно этим заниматься то устанавливай visual studio и выбирай там консольный проект

Автор: Metalex 11.11.2009, 11:05
Dev C++, журнал компиляции:
Цитата
Компілятор: Default compiler
Виконання  g++.exe...
g++.exe "D:\BORLANDC\BIN\5laba\3ZADACHA.CPP" -o "D:\BORLANDC\BIN\5laba\3ZADACHA.exe"    -I"C:\Dev-Cpp\include\c++"  -I"C:\Dev-Cpp\include\c++\mingw32"  -I"C:\Dev-Cpp\include\c++\backward"  -I"C:\Dev-Cpp\include"   -L"C:\Dev-Cpp\lib"
In file included from C:/Dev-Cpp/include/c++/backward/iostream.h:31,
                 from D:/BORLANDC/BIN/5laba/3ZADACHA.CPP:1:
C:/Dev-Cpp/include/c++/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <sstream> instead of the deprecated header <strstream.h>. To disable this warning use -Wno-deprecated.
D:/BORLANDC/BIN/5laba/3ZADACHA.CPP:49:2: warning: no newline at end of file

Виконання завершено
Компіляція успішна

Здесь есть какие-то предупреждения, но я не пойму какие..

Автор: N1ko 11.11.2009, 11:48
ну одна из ошибок Вместо <iostream.h> нужно писать <iostream> Это новый стандарт. Исходя из твоего изначального кода ещё нужно убрать getch () и conio.h так как это так это уже тоже не используется.  Перед каждым cin и cout напиши std:: Что это такое можешь почитать в инете. Благо инфы по этому поводу много. Вместо getch() используй cin.get(); фоператор принимающий один символ. 
<strstream.h> у тебя тож не правильный. Правда не помню для чего он юзается. В общем всё нужно заменить по новым стандартам. После того как прочтёшь это всё,и справишь и что то будет не получаться, кинь код - помогу.

Автор: ThisIsSparta 11.11.2009, 12:15
Цитата(Metalex @  10.11.2009,  22:43 Найти цитируемый пост)
getch() - это для задержки экрана, чтоб он не пропадал сразу же после выполнения программы. 

используй для этой цели лучше 
Код
std::cin.get();

Автор: N1ko 11.11.2009, 16:43
Ну я вообщето это написал )))) А здесь как бы между этими вариантами выбрать не получится, по этому слово лучше здесь мягко говоря не уместно. Ведь всё зависит только от компилятора насколько я знаю. Только в зависимости от него мы будем выполнять тот или инной оператор.

Автор: ThisIsSparta 11.11.2009, 17:12
Цитата(N1ko @  11.11.2009,  14:43 Найти цитируемый пост)
Ну я вообщето это написал ))))

мда, не заметил))
Цитата(N1ko @  11.11.2009,  14:43 Найти цитируемый пост)
Ведь всё зависит только от компилятора насколько я знаю. Только в зависимости от него мы будем выполнять тот или инной оператор.

не очень понял, это относится к cin.get() vs getch()? cin.get - это, насколько я знаю, кроссплатформенный вариант (из iostream), а getch() - не входит в стандартную библиотеку c++ (из conio.h).

Автор: N1ko 11.11.2009, 17:49
Я почему то думал что cin.get() в Borland 3.1 C++ не было ещё. Значит ошибался. =) Сорри =))

Автор: Metalex 12.11.2009, 00:20
ок займусь оптимизацией кода.

Автор: Metalex 12.11.2009, 01:06
Код
#include<iostream>
#include<string> //strlen

using namespace std;

int main()
{
int i, j, elem_i=0, elem_j=0, n, number=0;

std::cout<<"Vvedite tseloe n - kolishestvo vashih simvolov\n";
std::cin>>n;

char *str;
str=new char [n+1];

cin>>str;

int **word;
word=new int*[n];

for (i=0; i<(strlen(str)+1); i++)
{
    if ((str[i]==' ')||(str[i]=='\0'))
    {
        if ((str[i-1]!=' ')&(i!=0))
        {
            word[elem_i][0]=number;
            word[elem_i][1]=(i-1);
        }
        elem_i++;
    }
    else number++;
}

for (i=0; i<elem_i; i++)
for (j=0; j<2; j++)
std::cout<<word [i][j]<<"\n";

for (i=0; i<strlen(str); i++)
    delete word[i];

delete [] word;
delete [] str;
word=0;

std::cin.get();
return 0;
}

Массив с номерами не хочет выводится.

Автор: bsa 12.11.2009, 12:25
Metalex, 
Код
#include<string> //strlen
тебе дико повезло, что вообще скомпилировалось. Нужно подключать <cstring> для получения доступа к функциям strlen,strcpy и пр.
где ты выделяешь память под переменные типа int, которые инициализируешь в строках 27 и 28?

Автор: SemiC4 23.7.2010, 15:37
Цитата(mekhanikus @ 10.11.2009,  13:04)
Может стоит перейти на с++?
Вот пример из Страуструпа.
Программа считает количество повторений каждого слова.
До сабжа рукой подать.

Код

map<string,int>histogram;

void record(const string& s)
{
    histogram[s]++;
}

void print(const pair<const string,int>& r)
{
    cout << r.first << '\t' << r.second << '\n';
}

istream_iterator<string>ii(cin);
istream_iterator<string>eos;

for_each(ii,eos,record);
for_each(histogram.begin(),histogram.end(),print);

Здравствуйте, я токо начинаю. Читаю Страуструпа. вот этот пример про подчет количества вхождения слов в строке. у меня вопрос почему не заканчивается ввод, создается впечатление, что интер программа не воспринимет как конец ввода. и программа не выходит из алгоритма for_each(ii,eos,record);

Автор: azesmcar 23.7.2010, 17:15
Цитата(SemiC4 @  23.7.2010,  15:37 Найти цитируемый пост)
создается впечатление, что интер программа не воспринимет как конец ввода

естественно, конец ввода это Ctrl+Z.

Автор: djamshud 23.7.2010, 17:34
>конец ввода это Ctrl+Z

В DOS и Win. Исторически и в unix конец передачи (или файла) - ctrl+d.

Добавлено через 2 минуты и 40 секунд
Исторически - я имел в виду аски-код, забинденный на это сочестание.

Автор: SemiC4 23.7.2010, 20:08
Цитата(azesmcar @ 23.7.2010,  17:15)

естественно, конец ввода это Ctrl+Z.

огромное спасибо  smile  . щас ещё разберусь почему программа завершается раньше времени и будет вобще хорошоsmile smile 

Код
#include<iostream>
#include<algorithm>
#include<map>
#include<iterator>

bool quit()
{
    int tries = 1;
    while (tries < 4)
    {
          std::cout<<"\nWhould you like exit? yes(y) no(n)\n";
          char answer;
          std::cin>>answer;
          switch(answer)
          {
          case 'y':
               return true;
          case 'n':
               return false;
          default:
               {
               std::cout<<"repat answer\n";
               tries++;
               }
          }
    }
    std::cout<<"I think, you mean \"yes\"\n";
    return true;
}

std::map<std::string, int> histogram;

void record (const std::string &s)
{
         histogram[s]++;
}

void print (const std::pair<const std::string, int> &r)
{
         std::cout<<r.first<<' '<<r.second<<'\n';
}

int main()
{
do
{
    std::istream_iterator<std::string> ii (std::cin);
    std::istream_iterator<std::string> eos;

    std::for_each(ii, eos, record);
    std::for_each(histogram.begin(), histogram.end(), print);
}while(!quit());
return 0;
}


не пойму почему после того как я ввел строку, нажал интер, потом ctrl+z, интер, программа выводит результат и закрывается, причем пишется что программа завершилась с тем кодом что указан в ретуне функции майн smile 

Автор: bsa 23.7.2010, 22:32
SemiC4, читать надо начинать c http://forum.vingrad.ru/index.php?show_type=forum&showtopic=269794&kw=faq-c++

Автор: SemiC4 24.7.2010, 18:32
Цитата(bsa @ 23.7.2010,  22:32)
SemiC4, читать надо начинать c http://forum.vingrad.ru/index.php?show_type=forum&showtopic=269794&kw=faq-c++

Спасибо конечно за совет, но то что описано http://forum.vingrad.ru/forum/topic-269794/anchor-entry2099932/0.html (про быстрое закрытие программ, в самом конце) мне не помогло, потому как даже с такими изменениями в коде

Код
#include<iostream>
#include<algorithm>
#include<map>
#include<iterator>

bool quit()
{
    int tries = 1;
    while (tries < 4)
    {
          std::cout<<"\nWhould you like exit? yes(y) no(n)\n";
          char answer;
          std::cin>>answer;
          switch(answer)
          {
          case 'y':
               return true;
          case 'n':
               return false;
          default:
               {
               std::cout<<"repat answer\n";
               tries++;
               }
          }
    }
    std::cout<<"I think, you mean \"yes\"\n";
    return true;
}

std::map<std::string, int> histogram;

void record (const std::string &s)
{
         histogram[s]++;
}

void print (const std::pair<const std::string, int> &r)
{
         std::cout<<r.first<<' '<<r.second<<'\n';

         std::cin.ignore().get();
}

int main()
{
do
{
    std::istream_iterator<std::string> ii (std::cin);
    std::istream_iterator<std::string> eos;

    std::for_each(ii, eos, record);
    std::for_each(histogram.begin(), histogram.end(), print);

    std::cin.ignore().get();

}while(!quit());
return 0;
}

 

результат тот же smile 

Автор: bsa 25.7.2010, 17:24
блин. конечно тут не будет работать, так как после первого for_each поток std::cin перешел в состояние "конец файла" и из него больше ничего не читается. В данном случае, "паузу" можно сделать только через system("pause"), но функция quit() работать не будет. Решить проблему можно тремя путями:
1. читать значения из файла
2. зарезервировать определенное слово (или пустую строку) для выхода, например "quit" - в случае ее появления программа завершает ввод.
3. читать только определенное количество слов (например, предварительно спросив у пользователя)

Автор: SemiC4 25.7.2010, 18:58
Цитата(bsa @ 25.7.2010,  17:24)
блин. конечно тут не будет работать, так как после первого for_each поток std::cin перешел в состояние "конец файла" и из него больше ничего не читается. В данном случае, "паузу" можно сделать только через system("pause"), но функция quit() работать не будет. Решить проблему можно тремя путями:
1. читать значения из файла
2. зарезервировать определенное слово (или пустую строку) для выхода, например "quit" - в случае ее появления программа завершает ввод.
3. читать только определенное количество слов (например, предварительно спросив у пользователя)

Огромное спасибо, bsa smile . теперь что-то проясняется smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)