Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [c++]Работа со строками


Автор: maxnsk82 20.1.2010, 13:37
У меня задание: 
Функция переписывает строку. Если она находит в строке число, то вместо него она переписывает в выходную строку соответствующее по счету слово из входной строки. (например, "aaa bb1bb cc2cc" - "aaa bbaaabb ccbb1bbcc"). 

Пытался хотя бы строку перекинуть в функцию, а затем обратно, но тоже не работает:

Код

# include <stdio.h>
# include <conio.h>
# include <string.h>

char function(char C);

void main()
{
    char C[256];
    char word[10][128]; // предполагаю что массив под отдельные слова нужен
    printf ("Input words and numbers: \n");
    gets(C);
    printf ("New string: %s", function(C));
    getch();
}


char function(char C)
{
    return C;
}

Автор: Peter 20.1.2010, 14:02
В main() символ C имеет тип char[256], а в функции function() - char. Писать надо хотя бы
Код
char *function(char *C)
{
    return C;
}

Автор: maxnsk82 20.1.2010, 14:14
Проставил *. но так тоже не работает, ошибка: 'function': identifier not found.

Как сделать вообще не втыкаю(...мне бы работающий код, может тогда разберусь, уже 6 часов как пытаюсь сам сделать(

Автор: Luyan 20.1.2010, 18:31
Цитата(Peter @  20.1.2010,  14:02 Найти цитируемый пост)
В main() символ C имеет тип char[256], а в функции function() - char. Писать надо хотя бы

Цитата(maxnsk82 @  20.1.2010,  14:14 Найти цитируемый пост)
Проставил *. но так тоже не работает, ошибка: 'function': identifier not found.

одну? их 4 надо  smile 
Код

# include <stdio.h>
# include <conio.h>
# include <string.h>

char* function(char* str);
int main()
{
    char C[256] = {'4','5'};
    char word[10][128]; // предполагаю что массив под отдельные слова нужен
    printf ("Input words and numbers: \n");
    gets(C);
    printf ("New string: %s", function(C));
    getch();
    return 0;
}
char* function(char* str)
{
    return str;
}

Цитата(maxnsk82 @  20.1.2010,  13:37 Найти цитируемый пост)
Функция переписывает строку. Если она находит в строке число, то вместо него она переписывает в выходную строку соответствующее по счету слово из входной строки. (например, "aaa bb1bb cc2cc" - "aaa bbaaabb ccbb1bbcc"). 

В функцию передаётся массив, возвращать надо будет другой массив. Думаю реализовать надо так: сначала проходим по массиву С и записываем в word[j][i] до тех пор, пока не встретим пробел, затем кладём символ конца строки (word[0][i]= '\0'), и переходим на новую строку массива word и так далее. Потом начинаем копировать строку С в С2 и как только встречаем символ цифры (С[i] >= '0' && С[i] <= '9'), записываем нужную строку из массива word в С2, пока не встретим word[j][y] = '\0';, и так далее. Функция из двух циклов, в чём проблема?


Автор: maxnsk82 21.1.2010, 10:28
Кажется уже близко. но что-то не так в: word[i][j]='/0', не знаю почему?'=' : truncation from 'int' to 'char' и '=' : truncation of constant value - варнинги выдаёт. и что то с возвращаемым значением не то - туплю по поводу передачи параметров в функцию, никак не доходит(....помогите дописать:

Код

# include <stdio.h>
# include <conio.h>
# include <string.h>
char* function(char *str);
int main()
{
    char C[256];
    printf ("Input words and numbers: \n");
    gets_s(C);
    printf ("New string: %s", function(C));
    _getch();
    return 0;
}
char* function(char* str)
{
    char word[5][20];
    char newstr[256];
    int i=0,j=0,k=0;
    while (str[k] != '/0')                //-----------
    {                                    //
        while (str[k] != ' ')            //    Записываем отдельные слова
        {                                //    в массив word
            word[i][j]=str[k];            //
            j++;k++;                    //
        }word[i][j]='/0';i++;k++;j=0;    //
    }                                    //-----------
    i=0;j=0;k=0;int l=0;

    while (str[k] != '/0')    //пока не закончилась входящая строка..
    {
        if (str[k]<'1'||str[k]>'5')    //..если символ не цифра, переписываем
                                    //символ в новую строку
        {newstr[i]=str[k];i++;k++;}
        else                        //если цифра, то в зависимости от того
        {switch(str[k])                //какая, берём слово из массива word
            {                        // и посимвольно заносим в новую строку
            case '1':while (word[0][j] !='/0')
                     {newstr[i]=word[0][j];j++;i++;};break;
            case '2':while (word[1][j] !='/0')
                     {newstr[i]=word[0][j];j++;i++;};break;
            case '3':while (word[2][j] !='/0')
                     {newstr[i]=word[0][j];j++;i++;};break;
            case '4':while (word[3][j] !='/0')
                     {newstr[i]=word[0][j];j++;i++;};break;
            case '5':while (word[4][j] !='/0')
                     {newstr[i]=word[0][j];j++;i++;};break;
            }
        }
    }
    return newstr;
}

Автор: t_gran 21.1.2010, 10:57
Цитата

word[i][j]='/0', не знаю почему?'

Да потому, что нужно писать '\0' а не '/0'.

И основная ошибка, это то, что функция возвращает указатель на массив, память из под которого освобождается по завершению вашей функции. Поэтому, чтобы сильно не заморачиваться с кодом, сделайте массив newstr статичным (static), тогда всё заработает.

Автор: Luyan 21.1.2010, 11:32
Код

#include <stdio.h>
#include <conio.h>
#include <string.h>

char* function(char *str);
int main()
{
    char C[256] = {'a','a','a',' ','b','b','1','b','b',' ','c','c','2','c','c','\0'};
    printf ("Input words and numbers: \n");
    printf ("New string: %s", function(C));
    _getch();
    return 0;
}
char* function(char* str)
{
    char word[5][20];
    char newstr[256];
    int i=0,j=0,k=0;
    while(str[k] != '\0')
    {
        if(str[k] == ' ')
        {
            word[i][j] = '\0';
            i++;
        }    
        word[i][j] = str[k];         
       j++;k++;
    }
    i=0;j=0;k=0;int l=0;
    while(str[k] != '\0')
    {
        if(str[k] >= '1' && str[k] <= '5')
        {
            switch(str[k])
            {
                case '1':while (word[0][j] !='\0')
                     {newstr[i]=word[0][j];j++;i++;};break;
                case '2':while (word[1][j] !='\0')
                     {newstr[i]=word[1][j];j++;i++;};break;
                case '3':while (word[2][j] !='\0')
                     {newstr[i]=word[2][j];j++;i++;};break;
                case '4':while (word[3][j] !='\0')
                     {newstr[i]=word[3][j];j++;i++;};break;
                case '5':while (word[4][j] !='\0')
                     {newstr[i]=word[4][j];j++;i++;};break;
            }
            k++;j++;
        }
        else
        {
            newstr[i] = str[k];k++;i++;
        }
    }
    newstr[i] = '\0';
    return newstr;
}

поправил ваш код, в первом цикле немного не то делали, а во втором забыли 2 переменные инкрементировать.

Автор: maxnsk82 21.1.2010, 11:39
заменил: char static newstr[256]; "/" на "\" тоже везде, но не выполняется программа - ввод массива происходит, enter: такое вот сообщение: Unhandled exception at 0x00fe1540 in prog_lr3v13.exe: 0xC0000005: Access violation reading location 0x0000fb57. кнопки: break- выход/continue-сообщение так и остаётся(

Автор: t_gran 21.1.2010, 11:45
Цитата

заменил: char static newstr[256];


Код

static char newstr[256];


И всё тогда нормально выполняется. Не верите, см. прикреплённый файл.

Автор: wasistdas 21.1.2010, 12:02
Цитата(t_gran @ 21.1.2010,  11:45)
И всё тогда нормально выполняется. Не верите, см. прикреплённый файл.

Ваш вариант не работает и не работает он не из-за static. 
К автору вопроса, ваша прога вылетает при чтение str, потому что:
Код

   while (str[k] != '/0')                //-----------
    {                                    //
        while (str[k] != ' ')            //    Записываем отдельные слова
        {                                //    в массив word
            word[i][j]=str[k];            //
            j++;k++;                    //
        }word[i][j]='/0';i++;k++;j=0;    //
    }     

тут мы пролетает с последним символом, нужно ставить проверку во втором цикле на конец строки

Рабочий вариант:
Код

# include <stdio.h>
# include <conio.h>
# include <string.h>

char* function(char *str);

int main()
{
    char C[256];
    printf ("Input words and numbers: \n");
    gets_s(C);
    printf ("New string: %s", function(C));
    _getch();
    return 0;
}
char* function(char* str)
{
    char word[5][20];
    char newstr[256];
    int i=0,k=0;
    for(k=0;str[k]!='\0';k++)               
    {          
        int j = k;
        for(;str[j] != ' ' && str[j] != '\0';j++)
        {                                
            word[i][j-k]=str[j];            
        }
        word[i][j-k]='\0';

        if(str[j]=='\0')
            break;
        else
        {
            if(j>k)
            {
                i++;
                k=j-1;
            }
        }
    }   

    i=0;;k=0;int l=0;
    while(str[k] != '\0')
    {
        if(str[k] >= '1' && str[k] <= '5')
        {
            int j = 0;
            switch(str[k])
            {
                case '1':while (word[0][j] !='\0')
                     {newstr[i]=word[0][j];j++;i++;};break;
                case '2':while (word[1][j] !='\0')
                     {newstr[i]=word[1][j];j++;i++;};break;
                case '3':while (word[2][j] !='\0')
                     {newstr[i]=word[2][j];j++;i++;};break;
                case '4':while (word[3][j] !='\0')
                     {newstr[i]=word[3][j];j++;i++;};break;
                case '5':while (word[4][j] !='\0')
                     {newstr[i]=word[4][j];j++;i++;};break;
            }
            k++;j++;
        }
        else
        {
            newstr[i] = str[k];k++;i++;
        }
    }
    newstr[i] = '\0';
    return newstr;
}


Такой вопрос, а почему цифр то 5?)) а не 10.И еще не должна ли здесь быть рекурсия ?, т.е. дано: ааа ббб1ввв ггг2ддд -> 3 строка по вашему методу будет гггббб1вввддд, по-хорошему еще 1 можно разложить.

Автор: Luyan 21.1.2010, 12:26
я так смотрю, на мой рабочий исходник никто не посмотрел, все свои стали делать.  smile 
я же написал:
Цитата(Luyan @  21.1.2010,  11:32 Найти цитируемый пост)
в первом цикле немного не то делали

поэтому там и была ошибка. Я это исправил. Но хоть мой код рабочий, он не до конца верный, так как я начинал записывать второе слово в позицию word[1][4] и так далее, вариант wasistdas'а с первым циклом более правильный.
Цитата(wasistdas @  21.1.2010,  12:02 Найти цитируемый пост)
И еще не должна ли здесь быть рекурсия ?

думаю нет, смотри пример тс.
Цитата(maxnsk82 @  20.1.2010,  13:37 Найти цитируемый пост)
например, "aaa bb1bb cc2cc" - "aaa bbaaabb ccbb1bbcc"

Автор: maxnsk82 21.1.2010, 12:42
Всем спасибо!!!)  wasistdas - молодец) Рекурсия я думаю не нужна - ориентируясь по примеру. А то что чисел 5))..ну да в принципе не важно, вроде ещё есть время переправить до 9)...ещё раз спасибо! очень помогли!

Автор: Dancer 21.1.2010, 13:43
а ничего, что в задании написано "число", а вы организуете замену по "цифрам"? (скорее всего вся фишка задания именно в этом)
в таком случае, только первые 10 слов будут вставляться в дальнейший текст.
хотя конечно, если написать aaa121bbb то что нужно будет в это случае сделать? 
(слово 121; 
слово 1, слово 21; 
слово 1, слово 2, слово 1;
слово 12, слово 1) критерий выбора будет не понятен тогда, и что вставлять вместо слова с несуществующим индексом?

Наверное просто в задании ошибка.

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