Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/21: Рейтинг темы: голосов - 21, средняя оценка - 4.57
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14

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

23.03.2014, 18:25. Показов 4211. Ответов 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
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.03.2014, 18:25
Ответы с готовыми решениями:

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

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

Как передать значение в функцию так, чтобы при изменение значения в функции оно менялось во всей программе?
#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; void sum(int a) { a = 10; printf(&quot;%d\n&quot;, a); }

15
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
23.03.2014, 18:57
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
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14
23.03.2014, 19:02  [ТС]
Извините за глупый вопрос: 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
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
23.03.2014, 19:06
Цитата Сообщение от 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
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14
23.03.2014, 19:16  [ТС]
И еще один. А почему тогда одна функция работает с


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
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
23.03.2014, 19:34
Лучший ответ Сообщение было отмечено big_boom как решение

Решение

Цитата Сообщение от big_boom Посмотреть сообщение
я понял эту ошибку, но сейчас мучает вопрос почему функция работала с такой записью без
Без добавления '\0' или без копирования? Вы же с выделенной памятью и не работали. Выделяли и сразу теряли (указателю на эту память присваивали значение указателя, передаваемого в функцию). А дальше работа шла со строкой, которая передавалась в функцию.
2
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14
23.03.2014, 22:40  [ТС]
спасибо. все получилось) остался еще один вопрос. в коде строка 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
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
24.03.2014, 04:32
C++
1
using namespace std;
нужно помещать после всех инклудов.
Цитата Сообщение от big_boom Посмотреть сообщение
но если вместо этих двух строчек в каждой написать
C++
1
char *new_str = new char[]
то тогда проблема с их удалением. как удалить динамический массив во втором случае?
Массив так создавать не нужно (и в main()) тоже, попробуйте там освободить память из под str) (массив нулевого размера). Это не стандарт, но некоторые компиляторы такое допускают. В данном случае, тут будет ошибка (выход за пределы выделенной памяти).

Добавлено через 1 час 56 минут
И не нужно, в данном случае, передавать указатель в функцию по ссылке. Это делается, обычно, тогда, когда нужно, чтобы измения значения указателя в функции сохранились после выхода из функции. В данном коде, значения указателя, передаваемого в функцию, вообще не изменяется, поэтому и в передаче по ссылке смысла нет.
2
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14
24.03.2014, 15:43  [ТС]
Спасибо за советы. Очень помогли. Но к этой задачке надо еще одну ф-кцию дописать. Надо из строки выбрать все цифры и вывести их в новом динамическом массиве. Все сделал, есть одна проблема, которую не могу решить. Кажется, что разиер нового массива на цифры меньше чем количество цифр.
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
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
24.03.2014, 16:07
Лучший ответ Сообщение было отмечено big_boom как решение

Решение

Тут вообще непонятно, что делаете.
Опять массив нулевого размера:
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
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14
24.03.2014, 17:37  [ТС]
БОЛЬШОЕ ВАМ СПАСИБО!!! Очень помогли. Нашол очень странную ошыбку в коде
если написать
C++
1
gets_s(str, strlen(str))
то пишет L Buffer is too small &&0

а если просто
C++
1
gets(str)
то все ок.
В любом случае спасибо)
0
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
24.03.2014, 18:06
Цитата Сообщение от big_boom Посмотреть сообщение
Нашол очень странную ошыбку в коде
Советую не пользоваться не стандартными функциями (gets_s). Скорее всего, там вторым параметром идёт размер буфера, а размер его, предполагаю, должен быть strlen(str) + 1.
1
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14
27.03.2014, 13:35  [ТС]
Здраствуйте 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
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
27.03.2014, 13:58

Не по теме:

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



Добавлено через 5 минут
Не пойму только, почему вы ошибки не исправляете (о которых я писал)?
C++
1
2
3
4
char *str = new char[];
...
gets(str);
...
Добавлено через 1 минуту
И зачем здесь rewind(stdin)?
0
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 14
27.03.2014, 14:20  [ТС]
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
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
27.03.2014, 15:25
Цитата Сообщение от big_boom Посмотреть сообщение
использую для очистки буфера клавиатуры.
Я знаю для чего используется rewind(). Здесь он зачем? Ничего не делали, а поток уже испорчен? Или курсор не в начале?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.03.2014, 15:25
Помогаю со студенческими работами здесь

Как создать подобную прогу так чтобы при вводе разных чисел, изменялся размер зеленой полосы
Как создать подобную прогу так чтобы при вводе разных чисел, изменялся размер зеленой полосы

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

Ребят, что не так?(Хочу, чтобы при нажатии, Изменялся размер)
using System.Collections; using System.Collections.Generic; using UnityEngine; public class tap : MonoBehaviour { public...

Как сделать так, чтобы при выходе из программы она продолжала работать? (не вирус)
Пишу программу под Андроид. как сделать так, чтобы при выходе из программы она продолжала работать?, пример - будильник.

Как сделать так, чтобы изменялся шрифт именно выделенного текста?
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Spin,...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru