Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.12.2016, 00:26   #1
Mas0n_
Пользователь
 
Регистрация: 22.10.2016
Сообщений: 22
По умолчанию Функции и указатели. С++

Объясните, пожалуйста, почему в главной функции возвращается только один символ, хотя на самом деле в массиве записано больше? Программа выводит текст, составленный из последних букв всех слов.
Код:
#include <iostream>
#include <Windows.h> 
using namespace std;
char *ftext(char *str)
{
	char text[30];
	int i, k;
	for (i = 0, k = 0; str[i] != 0; i++) {
		if (str[i] == ' ') {
			*(text + k) = str[i - 1];
			k++;
		}
	}
	*(text + k) = str[i - 1];
	*(text + k + 1) = '\0';
	cout << text;
	return text;
}
void main()
{
	char s[30];
	SetConsoleCP(1251);
	SetConsoleOutputCP(1251);
	cout << "Введите строку: ";
	gets_s(s);
	cout << "Результат: " << *ftext(s) << endl;
Пример:
Введите строку: asd fg
dgРезультат: d

Последний раз редактировалось Mas0n_; 15.12.2016 в 00:29.
Mas0n_ вне форума Ответить с цитированием
Старый 15.12.2016, 01:34   #2
olej.tsil
Заблокирован
 
Регистрация: 29.11.2016
Сообщений: 215
По умолчанию

Цитата:
Сообщение от Mas0n_ Посмотреть сообщение
Код:
char *ftext(char *str)
{
   char text[30];
   ...
   return text;
Так делать нельзя!
Вы формируете строку в локальной переменной text в стеке.
Потом возвращаете указатель на эту локальную строку.
Но после возврата в вызывающую функцию ваш локальный стек функции ftext уже разрушен!
olej.tsil вне форума Ответить с цитированием
Старый 15.12.2016, 01:45   #3
Mas0n_
Пользователь
 
Регистрация: 22.10.2016
Сообщений: 22
По умолчанию

Как мне это исправить? Можете написать код?
Mas0n_ вне форума Ответить с цитированием
Старый 15.12.2016, 02:30   #4
ura_111
Участник клуба
 
Регистрация: 14.05.2016
Сообщений: 1,793
По умолчанию

А так:

Код:
#include <iostream>
#include <string>
using namespace std;

string ftext(char *str)
{
	string st;
	int i, k;
	for (i = 0, k = 0; str[i] != 0; i++) {
		if (str[i] == ' ') {
			st = st + str[i - 1];
			k++;
		}
	}
	st = st + str[i - 1];
	st = st + '\0';
	return st;
}
void main()
{
	char s[30];
	//SetConsoleCP(1251);
	//SetConsoleOutputCP(1251);
	cout << "Введите строку: ";
	gets_s(s);
	cout << "Результат: " << ftext(s) << endl;
	system("pause");
}

Последний раз редактировалось ura_111; 15.12.2016 в 03:30.
ura_111 вне форума Ответить с цитированием
Старый 15.12.2016, 10:00   #5
Mas0n_
Пользователь
 
Регистрация: 22.10.2016
Сообщений: 22
По умолчанию

Спасибо! Т.е. тут только со строками вариант? А можно с массивом как-нибудь? Мне просто нужно использовать указатель, как результат выполнения функции
Mas0n_ вне форума Ответить с цитированием
Старый 15.12.2016, 10:22   #6
olej.tsil
Заблокирован
 
Регистрация: 29.11.2016
Сообщений: 215
По умолчанию

Цитата:
Сообщение от Mas0n_ Посмотреть сообщение
А можно с массивом как-нибудь? Мне просто нужно использовать указатель, как результат выполнения функции
Можно:
Код:
char *ftext(char *str)
{
	static char text[30];
        ...
Всё остальное неизменно...
Но в более сложном коде этот вариант тоже с неожиданностями.
olej.tsil вне форума Ответить с цитированием
Старый 15.12.2016, 10:29   #7
netpolice
Форумчанин
 
Аватар для netpolice
 
Регистрация: 14.02.2013
Сообщений: 222
По умолчанию

Цитата:
Сообщение от olej.tsil Посмотреть сообщение
Можно:
Код:
char *ftext(char *str)
{
	static char text[30];
        ...
Всё остальное неизменно...
Но в более сложном коде этот вариант тоже с неожиданностями.
Память уплывать будет
netpolice вне форума Ответить с цитированием
Старый 15.12.2016, 11:58   #8
Mas0n_
Пользователь
 
Регистрация: 22.10.2016
Сообщений: 22
По умолчанию

Я вот как переделал. Именно так, как мне необходимо (задание: использовать динамические массивы и указатель, как результат выполнения функции).
Код:
#include <iostream>
#include <cstdio>
using namespace std;
char *fun(char(*));
void main()
{
	char *s;
	int n;
	cout << "Enter size of string: "; cin >> n;
	s = new char[n + 1];
	cout << "Enter string: ";
	gets(s);
	*fun(s);
	cout << "Result: " << s << endl;
	delete[] s;
}
char *fun(char *str)
{
	int i, k;
	for (i = 0, k = 0; *(str + i) != 0; ++i) {
		if (*(str + i) == ' ') {
			*(str + k) = *(str + i -1);
			k++;
		}
	}
	*(str + k) = *(str + i -1);
	*(str + k +1) = '\0';
	return str;
}
Но тут проблема в том, что через функцию gets() строка не вводится в дин. массив. Нашел такое решение: вместо gets(s) две строки
Код:
cin.get();
cin.getline(s, n + 1);
Тогда программа работает. Но я не понимаю, почему.
Объясните мне, пожалуйста. И можно ли как-нибудь по-другому через gets() выкрутиться? или через другие функции?
Mas0n_ вне форума Ответить с цитированием
Старый 15.12.2016, 12:12   #9
olej.tsil
Заблокирован
 
Регистрация: 29.11.2016
Сообщений: 215
По умолчанию

Цитата:
Сообщение от netpolice Посмотреть сообщение
Память уплывать будет
Куда она нафиг будет "уплывать"?
olej.tsil вне форума Ответить с цитированием
Старый 15.12.2016, 12:22   #10
olej.tsil
Заблокирован
 
Регистрация: 29.11.2016
Сообщений: 215
По умолчанию

Цитата:
Сообщение от Mas0n_ Посмотреть сообщение
И можно ли как-нибудь по-другому через gets() выкрутиться? или через другие функции?
Код:
string i;
getline( cin, i );
strncpy( s, i.c_str(), n );
... *fun( s );
...
olej.tsil вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Функции и указатели (СИ) ЕвгенийАйтишник Помощь студентам 0 26.06.2012 17:39
функции и указатели на C++ IcE^BeaR Помощь студентам 4 04.06.2012 18:45
Указатели на функции (си) Miles Помощь студентам 3 08.01.2012 23:30
Указатели на функции profi Общие вопросы C/C++ 20 12.07.2010 14:11
Функции и Указатели на С++ Wia Помощь студентам 3 17.04.2009 14:57