powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Реализация функции getline, для считывает потока ввода посимвольно посредством resize
25 сообщений из 42, страница 1 из 2
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39831445
MAGRAV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток господа.
Пишет вам человек, который слишком долго занимался VBA. Но речь не о том зачем это и как с этим бороться.
Речь и сложности восприятия концепции, что теперь казавшийся ранее простецкий string не так прост и с массивами в контексте VBA тоже всё было беззаботно. Но теперь нужно понимать и уметь реализовывать весь этот функционал в C++ без использования соответствующих библиотек. Только char, указатели и работа с памятью. Может что ещё забыл упомянуть.
Пытаюсь решить в образовательных целях следующую задачку:

Считываю поток ввода посимвольно пока не достигну конца потока и возвращаю C-style строку с прочитанными символами. В процессе чтения каждый раз перевыделяю память. Память возвращаемая из функции *getline() и *resize(...) будет освобождена оператором delete[].

Я как то не правильно подаю данные на вход в resize потому, что когда доходит дело до delete[], программа перестаёт выполняться корректно. Подскажите пожалуйста в чём я неправ?

Код: plaintext
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.
#include <iostream>

using namespace std;

char *resize(const char *str, unsigned size, unsigned new_size);
char *getline();

 int main()
{
	setlocale(LC_ALL, "Russian");
        char *b = getline();
	return 0;
}

char *resize(const char *str, unsigned size, unsigned new_size)
{
	char* ans = new char[new_size];
	for (int i = 0; i < size, i < new_size; ++i) {
		*(ans + i) = *(str + i);
	}
	delete[] str;
	return ans;
	/* ... */
}

char *getline()
{
	char c; 
	char * res = new char[0];
	int i = 0;
	unsigned size;
	unsigned new_size;
	//while (std::cin.get(c) && c != '\n' && c != std::cin.eof()){
	while (cin.get(c)) {
		if (c == '\n') {
			break;
		}
		if (i > 0) {
			size = i - 1;
			new_size = (++i) - 1;
			res = resize(res, i, new_size);
			res[i] = c;
		}else {
			res[i] = c;
			++i;
		}
	}
	if (i > 0) res = resize(res, i, ++i);
	res[i] = '\0';
	return res;
}
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39831457
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
строка в C/C++ в классическом ее понимании всегда должна заканчиваться нуль-терминатором, то есть у вас не может быть по определению

Код: plaintext
1.
2.
int i = 0;
char * res = new char[0];


надо так, хотя бы:
Код: plaintext
1.
2.
3.
int i = 1;
char * res = new char[1];
memset(res, 0, sizeof(char));


но лучше на 1 символ + нуль-терминатор:
Код: plaintext
1.
2.
3.
int i = 2;
char * res = new char[2];
memset(res, 0, sizeof(char) * 2);


В противном случае вы выделяете память в ноль байт и пытаетесь с ней работать. Зачем ?
Намного лучше и эффективнее с точки зрения производительности сократить обращения к менеджеру памяти и копирование до минимума, то есть изначально выделить некоторую область памяти и использовать ее пока она не будет исчерпана. Например, выделяем память на 10 символов + нуль-терминатор:
Код: plaintext
1.
2.
3.
4.
size_t szMemLeft = sizeof(char) * 10UL;
size_t szMemSize = szMemLeft + sizeof(char);
char * res = new char[szMemSize];
memset(res, 0, szMemSize);


По мере заполнения выделенного буфера, вы уменьшаете счетчик szMemLeft и когда он достигнет отметки 0, а символ \n еще не найден, наступает момент перенести содержимое из старого буфера в новый и переинициализировать szMemLeft и szMemSize. Новый буфер опять же лучше выделять сразу больше, например, удвоенного размера по сравнению с предыдущим, чтобы не выделять память под обному байту.

Для копирования участков памяти из старого буфера в новый лучше использовать memcpy_s, а не самописный цикл
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39831458
MAGRAV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Cerebrum,
Спасибо!
Успел и сам понять:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
char *getline()
{
	char c; 
    int i = -1;
	int sise = 1;
	char * res = new char[sise];
	while (cin.get(c) && c != '\n' && c != cin.eof()){
		res[++i] = c;
		res = resize(res, sise, ++sise);
	}
	res = resize(res, sise, ++sise);
	res[++i] = '\0';
	return res;
}
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39831460
MAGRAV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Cerebrum,
По поводу последнего абзаца с кодом и пояснением отдельное спасибо!

А так мне надо было решить задачку по работе с памятью именно в С++ стайл. А это операторы New+Delete и New[]+Delete[]
Ваше пояснение, как я понимаю, имеет отношение к C-стайлу (malloc, realloc, calloc, free).
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39831505
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MAGRAVА так мне надо было решить задачку по работе с памятью именно в С++ стайл. А это операторы
New+Delete и New[]+Delete[]
Ваше пояснение, как я понимаю, имеет отношение к C-стайлу (malloc, realloc, calloc, free).

Где ты там увидел у него malloc/free?

"Получить тормоза на ровном месте" это вовсе не "С++ стайл". Я бы (принимая во внимание
современные реалии) выделял память по килобайту, не меньше.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39831513
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИМХО если уж "С++ style", то используй std::vector .

Если "С style", то никаких new, delete, cin, т.к. это С++. Зато в С есть realloc()
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39831520
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По-хорошему просто взять std::string и не заниматься велосипедостроением
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39831524
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПо-хорошему просто взять std::string и не заниматься велосипедостроением
+1
ну или:
Код: plaintext
1.
std::vector<std::string> dataLine;


IMHO
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832027
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MAGRAV, ты уж определись что тебе по настоящему надо. С-style - это достаточно низкоуровневое
программирование где нет iostream.

Вот посмотри как в сях работают с файлами. Там файловые указатели FILE *, handles.

У тебя - какой-то микс С/C++. И правильно пишут дескыть - бери std::string. Бери и используй. Чего-тебе еще?

P.S. Вобщем... или трусы надень. Или крест сними.
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832038
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MAGRAV,
Одна из проблем в коде:
Код: plaintext
1.
for (int i = 0; i < size, i < new_size; ++i) {



В выделенном должно быть &&. А иначе только правая часть от "," ограничивает цикл, и при расширении строки вы читаете за пределами выделенного блока памяти, а при сокращении - пишете за его пределами (первое - возможный крэш, второе - гарантированно либо крэш либо поврежденная куча).

Ну а в целом перевыделять память каждый раз всего на один байт больше это перебор.
Если заранее размер не извествен, то выделять нужно в N раз больше чем предыдущий размер. N например 2 (но могут быть и другие).
И начальный размер ставьте какой-нибудь разумный типа 16 или даже 256. Потому что строка эта скорее всего короткоживущая, и лучше сократить кол-во выделений памяти чем экономить несколько сотен байт.
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832039
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
#include <iostream>
#include <string>

int main()
{
    std::string line;
    getline(std::cin, line);
    std::cout << line << std::endl;
}


Извините за.

ЗЫ. Хотя в образовательных целях полезно, как вы, извращаться.
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832074
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В тему статических анализаторов.

Недавно в форуме появлялся один господин который парил нам PVS-Studio.
Анализатор должен был среагировать на странное появлении операции запятая
в условии цикла.
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832095
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПо-хорошему просто взять std::string и не заниматься велосипедостроением
+1000000
нифига не понял, зачем писать велосипед
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832107
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудухнифига не понял, зачем писать велосипедну, например, с чем я последним столкнулся (пока 11-е не вышли) - невозможно передавать в конструктор строки "всё подряд", например чиселки, чтобы на выходе получать строку из числа. int 14 -> "14".

А, так да, после VB, где среда за всем бдит сама, трудно самому следить за деталями
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832228
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMb, для этого не нужно писать новую ф-ю string
уже опять же всё написано до нас:
Код: plaintext
1.
string s = to_string(42);


ИЛИ
Код: plaintext
1.
auto s = to_string(42);
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832433
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудухCEMb, для этого не нужно писать новую ф-ю string
уже опять же всё написано до нас:
Сказано же было "пока 11-е не вышли"
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832461
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пора на Haskell переходить. Не?
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832467
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyполудухCEMb, для этого не нужно писать новую ф-ю string
уже опять же всё написано до нас:
Сказано же было "пока 11-е не вышли"
они вышли 8 лет назад

так мы и C начнём вспоминать, какой там был ад

здесь современная ситуация, где человек пришёл изобретать велосипед в 2019
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832470
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonПора на Haskell переходить. Не?
он медленнее (
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832477
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonПора на Haskell переходить. Не?c C++ не переходють). Тут очень близко к железу.
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832479
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудухmaytonПора на Haskell переходить. Не?
он медленнее (
Возможно. Просто тут смотрю … борьба за красоту кода идет. Вот и вспомнил к месту.
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832514
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудухтак мы и C начнём вспоминать, какой там был ад

Ад будет когда приходишь в проект, а там никто с указателями не умел работать, и тебе это разгребать
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832520
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,
На старые проекты (легаси) наценки)) и молоко за вредность.
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832523
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"переходить" надо на клеточное программирование, вот куда надо стремиться
все эти груды железа ничто, по сравнению с маленькой точкой, которую мы всего 60 лет назад ещё толком разглядеть не могли
это самый совершенный ИИ из доступных нам
и он в "открытом доступе"
...
Рейтинг: 0 / 0
Реализация функции getline, для считывает потока ввода посимвольно посредством resize
    #39832524
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудух"переходить" надо на клеточное программирование, вот куда надо стремиться
все эти груды железа ничто, по сравнению с маленькой точкой, которую мы всего 60 лет назад ещё толком разглядеть не могли
это самый совершенный ИИ из доступных нам
и он в "открытом доступе"
Я так понимаю... дело в шляпе.

Остался пустяк.
...
Рейтинг: 0 / 0
25 сообщений из 42, страница 1 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / Реализация функции getline, для считывает потока ввода посимвольно посредством resize
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]