Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
big_boom
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14
#1

Как передать массив в функцию так, чтобы при выходе из функции он не изменялся? - C++

23.03.2014, 18:25. Просмотров 661. Ответов 15
Метки нет (Все метки)

Задачка: есть строка, которая состоит из символов. Символы соединяються в слова, которые оттделены друг от друга одним или несколькими пробелами. В конце текста крапка. написать:
1) Функцию, которая выводит все слова, без гласных литер;
2) Ф-кцию, которая выводит все слова без цыфр.

Задачку сделал и по-отдельно функции работают. Но когда запускаю функции друг за другом, то первая работает нормально, а вторая нет. Я думаю, это связано с тем, что изменяется начальный массив. Но не могу реализовать эти знания на практике. Мне не нужен код, мне нужно, чтобы кто-то обяснил почему моя прога работает так, где я допустил ошыбки и как их испрвить. Спасибо.


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <iostream>
using namespace std;
#include <cstring>
void Without_vowels(char *);
void With_numbers(char *);
int main()
{
    char *str = new char[];
    cout << "Enter the string: " << endl;
    rewind(stdin);
    gets_s(str, strlen(str));
 
 
    cout << "Words with numbers: ";
    With_numbers(str);
 
    cout << "Words without vowels: ";
    Without_vowels(str);
 
    
 
    return 0;
}
void Without_vowels(char *str4)
{
    char *new_str = new char[strlen(str4)];
    new_str = str4;
    char *vowels = { "AaOoIiUuYyEe" };
    char *ptrnastr;
    char *next_token;
    
 
    ptrnastr = strtok_s(new_str, " .", &next_token);
    while (ptrnastr != NULL)
    {
        bool check = true;
        for (int i = 0; i < strlen(ptrnastr); i++)
        {
            for (int j = 0; j < strlen(vowels); j++)
            {
                if (ptrnastr[i] == vowels[j])
                {
                    check = false;
                    break;
                }
 
            }
            if (check == false)
            {
                break;
            }
        }
        if (check == true)
        {
            cout << ptrnastr << " ";
        }
        
        ptrnastr = strtok_s(NULL, " .", &next_token);
        
    }
    //cout << str;
    //delete [] new_str;
 
}
void With_numbers(char *str5)
{
    char *numbers = { "0123456789" };
    char *str1 = new char;
    str1 = str5;
    char *ptrnachar;
    char*next_token = NULL;
    ptrnachar = strtok_s(str1, " .", &next_token);
    while (ptrnachar != NULL)
    {
        bool check = false;
        for (int i = 0; i < strlen(ptrnachar); i++)
        {
            for (int j = 0; j < strlen(numbers); j++)
            {
                if (ptrnachar[i] == numbers[j])
                {
                    check = true;
                    break;
                }
            }
 
            if (check == true)
            {
                break;
            }
        }
 
        if (check == true)
        {
            cout << ptrnachar << " ";
        }
        ptrnachar = strtok_s(NULL, " .", &next_token);
    }
 
 
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.03.2014, 18:25
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как передать массив в функцию так, чтобы при выходе из функции он не изменялся? (C++):

Как передать массив структур в функцию в качестве параметра, чтобы изменения в функции меняли исходный массив? - C++
Допустим есть структура struct Base { int a; int b; int c; }; В основном методе main() объявим массив...

Как передать в функцию два односвязных списка так, чтобы внутри функции можно было эти списки редактировать? - C++
Мне нужно редактировать в функции два односвязных списка, как их передать в функцию, один получается, два не понимаю как сделать....

как передать структуру в функцию, чтобы после выполнения функции он(массив в данном случае) вернулся измененным? - C++
const int size = 256; struct MARKER { char mark; } void processing(MARKER struct_m) { //тут какие-то изменения...

Не могу разобраться как передать корректно передать массив из функции в функцию - C++
//--------------------------------------------------------------------------- #pragma hdrstop ...

Как передать динамический массив в функцию, чтобы он изменился? - C++
Через указатель не изменяется:(

Как передать динамический массив из функции в другую функцию - C++
Здравствуйте.Не могу передать массив из функции в функцию сортировки. Подскажите как переделать программу : #include &quot;stdafx.h&quot; ...

15
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.03.2014, 18:57 #2
C++
1
2
3
4
5
void Without_vowels(char *str4)
{
    char *new_str = new char[strlen(str4)];
    new_str = str4;
...
Выделили память и тут же её потеряли.

Добавлено через 1 минуту
C++
1
2
3
4
5
void Without_vowels(char *str4)
{
    char *new_str = new char[strlen(str4) + 1];
    strcpy(new_str, str4);
...
Добавлено через 5 минут
И память, в функциях, не забудьте освободить.
0
big_boom
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14
23.03.2014, 19:02  [ТС] #3
Извините за глупый вопрос: char *new_str = new char[strlen(str4) + 1]; +1 это для терминатора, правильно?

и второй strcpy(new_str, str4); это то же самое что через for
C++
1
2
3
4
for (int i=0; i<strlen(str); i++)
{
new_str[i]=str4[i];
}
правильно ли я понимаю?


 Комментарий модератора 
обрамляем код тегом "С++"
0
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.03.2014, 19:06 #4
Цитата Сообщение от big_boom Посмотреть сообщение
Извините за глупый вопрос: char *new_str = new char[strlen(str4) + 1]; +1 это для терминатора, правильно?
Почему глупый? Вполне обычный вопрос, и вполне обычная ошибка. Да, для '\0'.

Добавлено через 1 минуту
Цитата Сообщение от big_boom Посмотреть сообщение
и второй strcpy(new_str, str4); это то же самое что через for
C++
1
2
3
4
for (int i=0; i<strlen(str); i++)
{
new_str[i]=str4[i];
}
правильно ли я понимаю?
Почти. '\0' забыли добавить. Или так сделать:
C++
1
2
3
4
for (int i = 0; i <= strlen(str); i++)
{
    new_str[i] = str4[i];
}
0
big_boom
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14
23.03.2014, 19:16  [ТС] #5
И еще один. А почему тогда одна функция работает с


C++
1
2
char *new_str = new char[strlen(str4)];
    new_str = str4;
я понял эту ошибку, но сейчас мучает вопрос почему функция работала с такой записью без


C++
1
2
3
4
5
void Without_vowels(char *str4)
{
    char *new_str = new char[strlen(str4) + 1];
    strcpy(new_str, str4);
...
0
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.03.2014, 19:34 #6
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от big_boom Посмотреть сообщение
я понял эту ошибку, но сейчас мучает вопрос почему функция работала с такой записью без
Без добавления '\0' или без копирования? Вы же с выделенной памятью и не работали. Выделяли и сразу теряли (указателю на эту память присваивали значение указателя, передаваемого в функцию). А дальше работа шла со строкой, которая передавалась в функцию.
2
big_boom
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14
23.03.2014, 22:40  [ТС] #7
спасибо. все получилось) остался еще один вопрос. в коде строка 27 и 69. Это я создаю new_char с определенным количеством элементов и с удалением нет проблем.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <iostream>
using namespace std;
#include <cstring>
void Without_vowels(char *&);
void With_numbers(char *&);
void Sorted_numbers(char *&str);
int main()
{
    char *str = new char[];
    cout << "Enter the string: " << endl;
    rewind(stdin);
    gets_s(str, strlen(str));
 
 
    cout << "Words with numbers: ";
    With_numbers(str);
 
    cout << "Words without vowels: ";
    Without_vowels(str);
 
    
 
    return 0;
}
void Without_vowels(char *&str)
{
    char *new_str = new char[strlen(str) + 1];
    strcpy(new_str, str);
    char *vowels = { "AaOoIiUuYyEe" };
    char *ptrnastr;
    char *next_token;
    
 
    ptrnastr = strtok_s(new_str, " .", &next_token);
    while (ptrnastr != NULL)
    {
        bool check = true;
        for (int i = 0; i < strlen(ptrnastr)+1; i++)
        {
            for (int j = 0; j < strlen(vowels); j++)
            {
                if (ptrnastr[i] == vowels[j])
                {
                    check = false;
                    break;
                }
 
            }
            if (check == false)
            {
                break;
            }
        }
        if (check == true)
        {
            cout << ptrnastr << " ";
        }
        
        ptrnastr = strtok_s(NULL, " .", &next_token);
        
    }
    //cout << str;
    delete [] new_str;
 
}
void With_numbers(char *&str)
{
    char *numbers = { "0123456789" };
    char *new_str = new char[strlen(str)+1];
    strcpy(new_str, str);
    char *ptrnachar;
    char*next_token = NULL;
    ptrnachar = strtok_s(new_str, " .", &next_token);
    while (ptrnachar != NULL)
    {
        bool check = false;
        for (int i = 0; i < strlen(ptrnachar)+1; i++)
        {
            for (int j = 0; j < strlen(numbers); j++)
            {
                if (ptrnachar[i] == numbers[j])
                {
                    check = true;
                    break;
                }
            }
 
            if (check == true)
            {
                break;
            }
        }
 
        if (check == true)
        {
            cout << ptrnachar << " ";
        }
        ptrnachar = strtok_s(NULL, " .", &next_token);
    }
    
    delete [] new_str;
 
}
но если вместо этих двух строчек в каждой написать
C++
1
char *new_str = new char[]
то тогда проблема с их удалением. как удалить динамический массив во втором случае?
0
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.03.2014, 04:32 #8
C++
1
using namespace std;
нужно помещать после всех инклудов.
Цитата Сообщение от big_boom Посмотреть сообщение
но если вместо этих двух строчек в каждой написать
C++
1
char *new_str = new char[]
то тогда проблема с их удалением. как удалить динамический массив во втором случае?
Массив так создавать не нужно (и в main()) тоже, попробуйте там освободить память из под str) (массив нулевого размера). Это не стандарт, но некоторые компиляторы такое допускают. В данном случае, тут будет ошибка (выход за пределы выделенной памяти).

Добавлено через 1 час 56 минут
И не нужно, в данном случае, передавать указатель в функцию по ссылке. Это делается, обычно, тогда, когда нужно, чтобы измения значения указателя в функции сохранились после выхода из функции. В данном коде, значения указателя, передаваемого в функцию, вообще не изменяется, поэтому и в передаче по ссылке смысла нет.
2
big_boom
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14
24.03.2014, 15:43  [ТС] #9
Спасибо за советы. Очень помогли. Но к этой задачке надо еще одну ф-кцию дописать. Надо из строки выбрать все цифры и вывести их в новом динамическом массиве. Все сделал, есть одна проблема, которую не могу решить. Кажется, что разиер нового массива на цифры меньше чем количество цифр.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
 
#include <cstring>
using namespace std;
void Without_vowels(char *&);
void With_numbers(char *&);
void Sorted_numbers(char *&str);
int main()
{
    char *str = new char[];
    cout << "Enter the string: " << endl;
    rewind(stdin);
    gets_s(str, strlen(str));
 
 
    //cout << "Words with numbers: ";
    //With_numbers(str);
 
    //cout << "Words without vowels: ";
    //Without_vowels(str);
 
    Sorted_numbers(str);
 
    
 
    return 0;
void Sorted_numbers(char *&str)
{
    char *numbers = { "0123456789" };
    int size = 0;
    char *new_str = new char[strlen(str) + 1];
    strcpy(new_str, str);
    char *str_with_numbers = new char[size];
    //char *ptrnastr, next_token = 0;
    int i = 0;
    while (new_str[i] != NULL)
    {       
            for (int j = 0; j < strlen(numbers); j++)
            {
                if (new_str[i] == numbers[j])
                {
                    ++size;
                    strcpy(&str_with_numbers[size-1], &new_str[i]);
                    
                    break;
                }
            }
 
            ++i;
        }
 
    str_with_numbers[size + 1] = '\0';
 
    
 
}
}
0
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.03.2014, 16:07 #10
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Тут вообще непонятно, что делаете.
Опять массив нулевого размера:
C++
1
2
3
int size = 0;
 ...   
char *str_with_numbers = new char[size];
Это лишнее:
C++
1
char *numbers = { "0123456789" };
Добавлено через 5 минут
Алгоритм должен быть, приблизительно, такой: подсчитываете количество цифр в строке (сравниваете каждый символ строки с диапазоном цифр (if (str[i] >= '0' && str[i] <= '9'), потом создаёте массив нужного размера, проходите второй раз по строке и копируете цифры в созданный массив.
0
big_boom
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14
24.03.2014, 17:37  [ТС] #11
БОЛЬШОЕ ВАМ СПАСИБО!!! Очень помогли. Нашол очень странную ошыбку в коде
если написать
C++
1
gets_s(str, strlen(str))
то пишет L Buffer is too small &&0

а если просто
C++
1
gets(str)
то все ок.
В любом случае спасибо)
0
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.03.2014, 18:06 #12
Цитата Сообщение от big_boom Посмотреть сообщение
Нашол очень странную ошыбку в коде
Советую не пользоваться не стандартными функциями (gets_s). Скорее всего, там вторым параметром идёт размер буфера, а размер его, предполагаю, должен быть strlen(str) + 1.
1
big_boom
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14
27.03.2014, 13:35  [ТС] #13
Здраствуйте alsav22. Хочу попросить помощь у вас еще один раз, поскольку вы доступно объясняете. Эту же самую задачку нам усложнили (если это можно так назвать). Нужно сделать функция сортировки слов по алфавиту. Между словами есть несколько пробелов. Все это нужно сделать с strtok. Понятия не имею з чего начать но вот моя попытка

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
using namespace std;
#include <cstring>
void Without_vowels(char *);
void With_numbers(char *);
void Sorted_numbers(char *);
void Sorted_words(char *);
int main()
{
    char *str = new char[];
    cout << "Enter the string: " << endl;
    rewind(stdin);
    gets(str);
 
    
 
    cout << "Sorted words: " << endl;
    Sorted_words (str);
    cout << endl;
 
    
 
    return 0;
}
 
void Sorted_words(char *str)
{
    char *ptrnachar;
    char *new_str = new char[strlen(str) + 1];
    strcpy(new_str, str);
    
    int number_words = 0;
    char *next_token2;
    ptrnachar = strtok_s(new_str, " .", &next_token2);
    
    while (ptrnachar != NULL)
    {
        number_words++; // s4itaem kol-vo slov
 
        ptrnachar = strtok_s(NULL, " .", &next_token2);
    }
 
    cout << number_words;
    //char **amount_words = new char*[number_words]; // masiv slov
    //for (int i = 0; i < number_words - 1; i++)
 
        
}
а дальше не знаю
0
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
27.03.2014, 13:58 #14

Не по теме:

Цитата Сообщение от big_boom Посмотреть сообщение
Все это нужно сделать с strtok
Когда я вижу strtok, меня, почему-то, начинает подташнивать. Может потому, что я Си не изучал? Какое-то у меня особое отношение имеено к этой функции...



Добавлено через 5 минут
Не пойму только, почему вы ошибки не исправляете (о которых я писал)?
C++
1
2
3
4
char *str = new char[];
...
gets(str);
...
Добавлено через 1 минуту
И зачем здесь rewind(stdin)?
0
big_boom
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14
27.03.2014, 14:20  [ТС] #15
C++
1
2
3
4
char *str = new char[255];
rewind(stdin);
gets(str);
delete[] str;
Добавлено через 15 минут
rewind (stdin)
использую для очистки буфера клавиатуры.
http://support.microsoft.com/kb/41159
0
27.03.2014, 14:20
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.03.2014, 14:20
Привет! Вот еще темы с ответами:

Как правильно передать динамический массив в функцию, увеличивающую его размер, чтобы изменения сохранились - C++
Извиняюсь за совсем нубский вопрос, похожее не нашел. Простая учебная задача - написать функцию, которая добавляет элемент в динамический...

Передача массива в несколько функций, чтобы исходный массив не изменялся - C++
Привет! Возник такой вопрос: Как передать исходный массив в несколько функции, так, чтобы исходный массив не изменялся ?

Функция создает объекты и указателями на них заполняет массив. При выходе из функции вызываются деструкторы объектов. Как сохранить объекты? - C++
Вопрос прост: как при выходе из функции сохранить объекты, которые были созданы в данной функции (указатели объектов положены в массив)?

Передать массив в функцию и вернуть из функции - C++
Доброго времени суток. Пытаюсь считать из файлов числа и попарно их перемножить. Проблема в функциях void EnterMassive и void Multi. В...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru