Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++] Разбить строку на числа и символы 
V
    Опции темы
m0zg
Дата 20.4.2008, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.7.2007

Репутация: нет
Всего: 2



Задача такая:
Из входного потока вводится произвольное число строк, состоящих из последовательности десятичных многоразрядных чисел и слов, которые могут быть не разделены, либо разделены один/несколькими пробелами/знаками табуляции. Длина строки не превышает 80 символов. Конец ввода определяется концом файла.

При обработке строк сформитровать 2 новые, поместив в первую числа, во втроую слова. Числа и слова должны быть разделены только один пробелом. Полученные строки вывести на экран.


P.S. Ввод нужно сделать с помощью cin.getline(куда, максимум_сколько). Библиотечные функции обработки строк не использовать.

Вопрос такой для начала. Как в функции различать что есть символ, что есть цифра? И раскидать их по разным массивам.
PM MAIL   Вверх
piritus
Дата 20.4.2008, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 226
Регистрация: 3.1.2007
Где: Сибирь

Репутация: 1
Всего: 3



Код

if (chr >= 'A' && chr <= 'Z'){...}


или если строка:
Код

int i;
for(i=0;i<strlen(chr);i++)
if (chr[i] >= 'A' && chr[i] <= 'Z'){...}

так же с цифрами
--------------------
PM MAIL ICQ   Вверх
m0zg
Дата 20.4.2008, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.7.2007

Репутация: нет
Всего: 2



нельзя использовать функции из string.h
PM MAIL   Вверх
Evjeny
Дата 20.4.2008, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 14.8.2006

Репутация: 3
Всего: 5



Цитата(m0zg @  20.4.2008,  20:55 Найти цитируемый пост)
Вопрос такой для начала. Как в функции различать что есть символ, что есть цифра? И раскидать их по разным массивам.


Извиняюсь, че-то я ошибся, надо вот так

Код

    char str[20];

    char ch[20]; //массив для символов
    char num[20]; //массив для цифр

    cout << "Enter string: ";

    cin.getline(str, 20);

    int i = 0, j = 0,k = 0;

    while(str[i])
    {
        if((str[i]>='A'&&str[i]<='Z')||(str[i]>='a'&&str[i]<='z'))
            ch[j++] = str[i];

        if(str[i]>='0'&&str[i]<='9')
            num[k++] = str[i];

        i++;
    }


Это сообщение отредактировал(а) Evjeny - 21.4.2008, 13:56
PM MAIL WWW   Вверх
m0zg
Дата 24.4.2008, 01:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.7.2007

Репутация: нет
Всего: 2



Я тут пишу эту программку и возникла проблемка. Почему функция filter не вырезает символы-разделители?

Код
#include <iostream>

using namespace std;
const int SIZE = 80;

void form(char *in, char *out);
void filter(char *from, char *to);

int main(){
    char buf[SIZE], outbuf[SIZE], tmp[SIZE];
    while(cout << "Enter string: ", cin.getline(tmp, SIZE)){
        filter(tmp, buf);
        //form(buf, outbuf);
        //cout << "Result string: " << outbuf << endl;
        cout << "Result string: " << buf << endl;
    }
}

void form(char *in, char *out){
    int i = 0, j = 0, k = 0;
    int num[80];
    char chr[80];
    while(in[i])
    {
        if((in[i]>='A' && in[i]<='Z')||(in[i]>='a' && in[i]<='z')){
            chr[j++] = in[i];
        }
        if(in[i]>='0' && in[i]<='9'){
            num[k++] = in[i];
        }
        i++;
    }
}

void filter(char *from, char *to){
    int i = 0, j = 0;
    while(from[i]!='\0'){
        if(from[i]!=' ' && from[i]!='\t'){
            to[j++] = from[i];
        }
        if(from[i+1]==' ' || from[i+1]=='\t' || from[i+1]=='\0'){
            to[j++] = ' ';
        }
        i++;
    }
    to[i-1] = '\0';
}

PM MAIL   Вверх
piritus
Дата 24.4.2008, 07:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 226
Регистрация: 3.1.2007
Где: Сибирь

Репутация: 1
Всего: 3



Код

void filter(char *from,char *to){
int i=0,j=0;
bool flag=0;

    while(from[i]!='\0'){
        if(from[i]==' ' || from[i]=='\t')
            if(flag==0){
              to[j]=' ';
              j++;
              flag=1;
            }

        if(from[i]!=' ' && from[i]!='\t'){
            to[j]=from[i];
            j++;
            flag=0;
        }
        i++;
    }
    to[j]='\0';
}

--------------------
PM MAIL ICQ   Вверх
m0zg
Дата 3.5.2008, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.7.2007

Репутация: нет
Всего: 2



Вот, что у меня тут получается, но какой-то непонятный для меня глюк после ввода происходит. Когда после Enter string я нажимаю на enter, даже ничего не вводя, выводиться какая-то кракозябра. А если ввожу сиволы и цифры, то тоже хрень какая-то происходит. Мне препод подсказывал, подсказывал, так я правильно и не смог написать. Или может что-то не дописал? Я вообще с этими указателями не очень дружу )). В чем тут может быть дело?

Код

#include <iostream>

using namespace std;
const int SIZE = 80;

void form(char *in, char *outDigits, char *outLetters);
char *skip(char *str);
char *copyDigits(char *&from, char *to);
char *copyLetters(char *&from, char *to);

int main(){
    char buf[SIZE], outDigits[SIZE], outLetters[SIZE];
    while(cout << "Enter string: ", cin.getline(buf, SIZE)){
        form(buf, outDigits, outLetters);
        cout << "Result string: " << outDigits << endl << outLetters << endl;
    }
}

void form(char *in, char *outDigits, char *outLetters){
    while( *(in = skip(in)) ){
        if(*in >= '0' && *in <= '9'){
            outDigits = copyDigits(in, outDigits);
        } else {
            outLetters = copyLetters(in, outLetters);
        }
    }
}

// в этой функции пропускаем все, кроме букв и цифр
char *skip(char *str)
{
    while(*str && (*str<'0' && *str>'9' || *str<'A' && *str>'Z' || *str<'a' && *str>'z')){
        str++;
    }
    return str;
}

//формирую строку с цифрами
char *copyDigits(char *&from, char *to)
{
    while(*from >= '0' && *from <= '9'){
        *to++ = *from++;
    }
    *to++ = ' ';
    *to = '\0';
    return to;
}

//строку с буквами
char *copyLetters(char *&from, char *to)
{
    while(*from >= 'A' && *from <= 'Z' && *from >= 'a' && *from <= 'z'){
        *to++ = *from++;
    }
    *to++ = ' ';
    *to = '\0';
    return to;
}

PM MAIL   Вверх
m0zg
Дата 10.5.2008, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.7.2007

Репутация: нет
Всего: 2



Правильный вариант. Проверенный и зачтенный smile

Код

#include <iostream>

using namespace std;
const int SIZE = 80;

void form(char *in, char *outDigits, char *outLetters);
char *skip(char *str);
char *copyDigits(char *&from, char *to);
char *copyLetters(char *&from, char *to);

int main(){
    char buf[SIZE], outDigits[SIZE], outLetters[SIZE];
    while(cout << "Enter string: ", cin.getline(buf, SIZE)){
        form(buf, outDigits, outLetters);
        cout << "Result string: " << outDigits << endl << outLetters << endl;
    }
}

void form(char *in, char *outDigits, char *outLetters){
    while( *(in = skip(in)) ){
        if(*in >= '0' && *in <= '9'){
            outDigits = copyDigits(in, outDigits);
        } else {
            outLetters = copyLetters(in, outLetters);
        }
    }
    *outDigits = '\0';
    *outLetters = '\0';
}

char *skip(char *str)
{
    while(*str && ((*str<'0' || *str>'9') && (*str<'A' || *str>'Z') && (*str<'a' || *str>'z'))){
        str++;
    }
    return str;
}

char *copyDigits(char *&from, char *to)
{
    while(*from >= '0' && *from <= '9'){
        *to++ = *from++;
    }
    *to++ = ' ';
    return to;
}

char *copyLetters(char *&from, char *to)
{
    while(*from >= 'A' && *from <= 'Z' || *from >= 'a' && *from <= 'z'){
        *to++ = *from++;
    }
    *to++ = ' ';
    return to;
}



Теперь нужно эту прогу переделать со списками и динамической памятью.
Каждая строка представлена списком; первое поле элемента списка - символ строки; второе - указатель на следующий элемент списка или NULL в конце списка. Ввод по такой же схеме, пока не конце - cin.getline(); сформировать список; обработать список в соответствии с условием задачи; вывести результат и освободить память, выделенную под список.
PM MAIL   Вверх
m0zg
Дата 11.5.2008, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.7.2007

Репутация: нет
Всего: 2



Народ, подскажите в чем проблема и где? Я тут написал сам толком не понимаю что сделал  :blink:  После ввода строки с буквами и цифрами (по заданию, оно написано выше) програма вылетает с ошибкой сегментации.

Код

#include <iostream>

using namespace std;
const int SIZE = 80;

struct Item {
    char s;
    Item *next;
};

Item *erase(Item *&str);
Item *createList(char *str);
void *form(Item *in, Item *outDigits, Item *outLetters);
Item *skip(Item *str);
Item *copyDigits(Item *&from, Item *to);
Item *copyLetters(Item *&from, Item *to);
void showDigits(Item *outDigits);
void showLetters(Item *outLetters);

int main(){
    Item *list = NULL, *outDigits = NULL, *outLetters = NULL;
    char buf[SIZE];
    while(cout << "Enter string: ", cin.getline(buf, SIZE)){
        list = createList(buf);
        form(list, outDigits, outLetters);
        cout << "Result string: ";
        showDigits(outDigits);
        cout << endl;
        showLetters(outLetters);
        cout << endl;
        erase(outDigits);
        erase(outLetters);
        erase(list);
    }
}

void *form(Item *in, Item *outDigits, Item *outLetters){
    while(in = skip(in)){
        if(in->s >= '0' && in->s <= '9'){
            outDigits = copyDigits(in, outDigits);
        } else {
            outLetters = copyLetters(in, outLetters);
        }
    }
}

Item *skip(Item *str)
{
    while(str && ((str->s < '0' || str->s > '9') && (str->s < 'A' || str->s > 'Z') && (str->s < 'a' || str->s > 'z'))){
        str->s = str->s++;
    }
    return str;
}

void showDigits(Item *outDigits){
    Item *k = outDigits;
    while(k){
        cout << k->s;
        k = k->next;
    }
    cout << " ";
}

void showLetters(Item *outLetters){
    Item *k = outLetters;
    while(k){
        cout << k->s;
        k = k->next;
    }
    cout << " ";
}

Item *createList(char *str){
    Item *begin = NULL, *end = NULL;
    if(str == ""){
        return NULL;
    }
    while(*str){
        Item *k = new Item;
        k->s = *str++;
        k->next = NULL;
        if(begin == NULL){
            begin = k;
        } else {
            end->next = k;
        }
        end = k;
    }
    return begin;
}

Item *erase(Item *&str){
    Item *tmp;
    while(str){
        tmp = str;
        str = str->next;
        delete tmp;
    }
    return NULL;
}

Item *copyDigits(Item *&from, Item *to)
{
    Item *last = from;
    while(from->s >= '0' && from->s <= '9'){
        Item *k = new Item;
        k->s = to->s;
        k->next = NULL;
        if(last == NULL){
            from = k;
        } else {
            last->next = k;
        }
        last = k;
        to = to->next;
    }
//    to->s++ = ' ';
    return to;
}

Item *copyLetters(Item *&from, Item *to)
{
    Item *last = from;
    while(from->s >= 'A' && from->s <= 'Z' || from->s >= 'a' && from->s <= 'z'){
        Item *k = new Item;
        k->s = to->s;
        k->next = NULL;
        if(last == NULL){
            from = k;
        } else {
            last->next = k;
        }
        last = k;
        to = to->next;
    }
    //to->s++ = ' ';
    return to;
}


PM MAIL   Вверх
m0zg
Дата 16.5.2008, 01:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.7.2007

Репутация: нет
Всего: 2



Народ, помогите отладить программу  smile .
Ввожу строку, например: erttt3456345fhfsgh rth  5673567 356.

А результат: 3456345 0 0 05673567 0356
erttt fhfsgh rth

Т.е. после каждого пробела вставляется ноль, не пойму почему. Причем, происходитӕто только в строке(функции) с цифрами. 
Даже, если я просто ввожу пробел, то в результирующей строке будет выведен ноль  smile 

Код

#include <iostream>

using namespace std;
const int SIZE = 80;

struct Item {
    char s;
    Item *next;
};

Item *erase(Item *&str);
Item *createList(char *str);
void *form(Item *in, Item *&outDigits, Item *&outLetters);
Item *skip(Item *str);
Item *copyDigits(Item *&from, Item *&to);
Item *copyLetters(Item *&from, Item *&to);
void showItem(Item *list);

int main(){
    Item *list = NULL, *outDigits = NULL, *outLetters = NULL;
    char buf[SIZE];
    while(cout << "Enter string: ", cin.getline(buf, SIZE)){
        list = createList(buf);
        form(list, outDigits, outLetters);
        cout << "Result string: ";
        showItem(outDigits);
        cout << endl;
        showItem(outLetters);
        cout << endl;
        erase(outDigits);
        erase(outLetters);
        erase(list);
    }
}

//создаю список из введенной строки
Item *createList(char *str){
    Item *begin = NULL, *end = NULL;
    if(str == ""){
        return NULL;
    }
    while(*str){
        Item *k = new Item;
        k->s = *str++;
        k->next = NULL;
        if(begin == NULL){
            begin = k;
        } else {
            end->next = k;
        }
        end = k;
    }
    return begin;
}

//создаю головные элементы, фильтрую и раскидываю по соответствующим спискам
void *form(Item *in, Item *&outDigits, Item *&outLetters){
    Item headDigits = {' ', NULL}, headLetters = {' ', NULL};
    outDigits = &headDigits;
    outLetters = &headLetters;
    while(in = skip(in)){
        if(in->s >= '0' && in->s <= '9'){
            outDigits = copyDigits(in, outDigits);
        } else {
            outLetters = copyLetters(in, outLetters);
        }
    }
    outDigits = headDigits.next;
    outLetters = headLetters.next;
}

//фильтр
Item *skip(Item *str)
{
    while(str && ((str->s < '0' || str->s > '9') && (str->s < 'A' || str->s > 'Z') && (str->s < 'a' || str->s > 'z'))){
        str->s = str->s++;
    }
    return str;
}

//создаем список цифр
Item *copyDigits(Item *&from, Item *&to)
{
    while(from!=NULL && (from->s >= '0' && from->s <= '9')){
        Item *k = new Item;
        k->s = from->s;
        k->next = NULL;
        to->next = k;
        to = k;
        from = from->next;
    }
    to->next = new Item;
    to = to->next;
    to->s = ' ';
    to->next = NULL;
    return to;
}

//создаем список букв
Item *copyLetters(Item *&from, Item *&to){
    while(from!=NULL && (from->s >= 'A' && from->s <= 'Z' || from->s >= 'a' && from->s <= 'z')){
        Item *k = new Item;
        k->s = from->s;
        k->next = NULL;
        to->next = k;
        to = k;
        from = from->next;
    }
    to->next = new Item;
    to = to->next;
    to->s = ' ';
    to->next = NULL;
    return to;
}

//выводим список
void showItem(Item *list){
    while(list){
        cout << list->s;
        list = list->next;
    }
}

//очищаем память
Item *erase(Item *&str){
    Item *tmp;
    while(str){
        tmp = str;
        str = str->next;
        delete tmp;
    }
    return NULL;
}



Это сообщение отредактировал(а) m0zg - 16.5.2008, 01:27
PM MAIL   Вверх
Evjeny
Дата 16.5.2008, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 14.8.2006

Репутация: 3
Всего: 5



В функции
Код

Item *skip(Item *str);

исправь строку
Код

str->s = str->s++;

на
Код

str = str->next;

PM MAIL WWW   Вверх
m0zg
Дата 16.5.2008, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.7.2007

Репутация: нет
Всего: 2



Блиин, точно! Спасибо большое  smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0957 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.