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

Реализация своей функции getline

12.10.2015, 09:08. Показов 21527. Ответов 57
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте! Не могу решить задачку.

Постановка:
Реализуйте функцию getline, которая считывает поток ввода посимвольно, пока не достигнет конца потока или не встретит символ переноса строки ('\n'), и возвращает C-style строку с прочитанными символами.

Обратите внимание, что так как размер ввода заранее неизвестен, то вам нужно будет перевыделять память в процессе чтения, если в потоке ввода оказалось больше символов, чем вы ожидали.

Память, возвращенная из функции будет освобождена оператором delete[]. Символ переноса строки ('\n') добавлять в строку не нужно, но не забудьте, что в конце C-style строки должен быть завершающий нулевой символ.

Мой код:

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
#include <iostream>
using namespace std;
 
char *getline()
{
    char *m = new char[1];
    char c;
    cin >> c;
    int i = 1;
 
    while ((c != '\n') && (c != '\0')) {
        m = new char[i];
        m[i-1] = c;
        i++;
    }
    
    m[i] = '\0';
 
    return m;
    
}
 
int main(void) {
    char *example = getline();
    system("pause");
    return 0;
}
Вопрос:
В чем ошибка ? Консоль зависает после перехода на новую строку.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.10.2015, 09:08
Ответы с готовыми решениями:

Реализация getline
Добрый день. Новичок в программировании. Нужна помощь. Есть код: #include &lt;iostream&gt; #include...

Реализация функций getline
Помогите разобраться , как производится подсчет строк в этом коде. #include &quot;pch.h&quot;...

Delim в функции getline()
Здравствуйте. Встала проблема, что при чтении файла нужно использовать разные разделяемые символы...

Какой правильный вызов у функции getline()?
FILE *db; char file = &quot;Quiz.csv&quot;; string str; db = fopen(file, &quot;r&quot;); getline(db, str, &quot;/n&quot;);...

57
13 / 13 / 6
Регистрация: 29.09.2015
Сообщений: 38
12.10.2015, 09:41 2
У вас цикл бесконечный 11-15 строки.
Внутри цикла переменная с не изменяется.

В 12 строке вы указателю m присваиваете новое значение при этом не освобождаете память на которую он указывал.
1
202 / 138 / 88
Регистрация: 21.12.2014
Сообщений: 369
12.10.2015, 09:45 3
1) Память надо освобождать.
C++
1
2
3
4
5
6
7
while ((c != '\n') && (c != '\0')) {
        delete []m;
        m = new char[i];
        m[i-1] = c;
        i++;
    }
    }
2)
C++
1
m[i-1] = '\0';
3)
Цитата Сообщение от alexvikt Посмотреть сообщение
У вас цикл бесконечный 11-15 строки.
Внутри цикла переменная с не изменяется.
1
1 / 1 / 0
Регистрация: 23.09.2015
Сообщений: 42
12.10.2015, 15:06  [ТС] 4
Исправил так:
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
#include <iostream>
using namespace std;
 
char *getline()
{
    char *m = new char[1];
    char c;
    cin >> c;
    int i = 1;
        
        m[0] = c;
    while ((c != '\n') && (c != '\0')) {
 
 
        char *temp = new char[i];
        for (int j = 0; j < i - 1; j++) {
            temp[j] = m[i];
        }
        temp[i - 1] = c;
 
        delete[] m;
        m = new char[i];
 
        for (int j = 0; j < i; j++) {
            m[i] = temp[i];
        }       
 
        i++;
 
        delete[] temp;
        cin >> c;
 
    }
    
    m[i] = '\0';
 
    return m;
    
}
 
int main(void) {
    char *example = getline();
    system("pause");
    return 0;
}
Программа почему-то находится в бесконечном цикле и не видит переход на новую строку.
0
7793 / 6560 / 2984
Регистрация: 14.04.2014
Сообщений: 28,672
12.10.2015, 15:12 5
Операция >> считает '\n' разделителем и отбрасывает. Используй get().
1
Эксперт PHP
3106 / 2591 / 1219
Регистрация: 14.05.2014
Сообщений: 7,236
Записей в блоге: 1
12.10.2015, 15:34 6
Цитата Сообщение от Redzep Посмотреть сообщение
C++
1
2
3
4
delete []m;
m = new char[i];
m[i-1] = c;
i++;
плохой совет - не нужно сначала освобождать память, а затем копировать, нужно наоборот.

Добавлено через 21 минуту
JustForStudy, попробуйте так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
char * getline()
{
    char c;
    char *m = nullptr, *temp = nullptr;
    int i = 2, j = 0;
    while(c = std::cin.get())
    {
        if (c == '\n' || c == 0) break;
        temp = m;
        m = new char[i]();
        for (j = 0; j < i-2; ++j)
            m[j] = temp[j];
        delete[] temp;
        m[j] = c;
        ++i;
    }
    
    return m;
}
1
1 / 1 / 0
Регистрация: 23.09.2015
Сообщений: 42
14.10.2015, 15:24  [ТС] 7
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
std::cin.get()
А что это значит ?
0
7793 / 6560 / 2984
Регистрация: 14.04.2014
Сообщений: 28,672
14.10.2015, 15:40 8
Извлечь 1 символ.
1
1 / 1 / 0
Регистрация: 23.09.2015
Сообщений: 42
14.10.2015, 15:51  [ТС] 9
Вроде бы
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
плохой совет - не нужно сначала освобождать память, а затем копировать, нужно наоборот.
Попробовал вашу программу - вроде работает, но тестирование не проходит.

Попробовал исправить свою, в итоге она зависает в цикле. Не подскажете в чем снова я накосячил ?

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
char * getline() {
 
    char c = cin.get();
    char *m = new char[2];
    m[0] = c;
 
    int i = 1;
 
    while ((c != '\n') || (c != 0)) {
 
        c = cin.get();
        m[i] = c;
        char *temp = m;
 
        delete[] m;
        i++;
        m = new char[i+1];
 
        for (int j = 0; j < i; j++) {
            m[j] = temp[j];
        }
    }
    
    m[i + 1] = 0;
 
    return m;   
}
0
7793 / 6560 / 2984
Регистрация: 14.04.2014
Сообщений: 28,672
14.10.2015, 16:01 10
Сначала создать новую строку, скопировать туда и только после delete.
1
13 / 13 / 6
Регистрация: 29.09.2015
Сообщений: 38
14.10.2015, 16:01 11
13 и 15 строки.
temp это указатель на m, удалив m, temp указывает в никуда.
1
Эксперт PHP
3106 / 2591 / 1219
Регистрация: 14.05.2014
Сообщений: 7,236
Записей в блоге: 1
14.10.2015, 16:01 12
JustForStudy, а можно название сайта и номер задачи узнать?
1
1 / 1 / 0
Регистрация: 23.09.2015
Сообщений: 42
14.10.2015, 18:32  [ТС] 13
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
JustForStudy, а можно название сайта и номер задачи узнать?
Да, конечно. Сайт "Степик", курс "Программирование на языке C++", урок 2.6, задача 1.

Добавлено через 2 часа 3 минуты
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
delete[] temp;
А как компилятор узнает какое количество ячеек в памяти необходимо удалить ? Это же указатель.
0
Эксперт PHP
3106 / 2591 / 1219
Регистрация: 14.05.2014
Сообщений: 7,236
Записей в блоге: 1
14.10.2015, 18:48 14
Цитата Сообщение от JustForStudy Посмотреть сообщение
А как компилятор узнает какое количество ячеек в памяти необходимо удалить ?
Поверьте, он знает, - особенности реализации операторов new[] и delete[].
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
14.10.2015, 20:24 15
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
#include <iostream>
#include <cstring>
 
using namespace std;
 
char* getline(){
 
     char *str = new char[1];
     str[0] = 0;
     char ch;
     char *buf;
     int len;
 
 
    while ( ch = cin.get() ){
        if (ch == '\n') break;
 
        len = strlen(str);
        buf = new char[len+2];
        strcpy(buf,str);
        buf[len] = ch;
        buf[len+1] = 0;
        delete []str;
        str = buf;
 
    }
 
    return str;
 
}
 
int main()
{
    char *pch =   getline();
       cout << pch;
    delete []pch;
}
1
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,523
14.10.2015, 20:28 16
поскольку нет вызовов конструкторов я бы воспользовался
malloc realloc free
realloc сам перевыделит память и сам все скопирует
и перевыделял бы память не по 1 символу а допустим по 100, скорость возрастет
1
1 / 1 / 0
Регистрация: 23.09.2015
Сообщений: 42
15.10.2015, 09:39  [ТС] 17
Цитата Сообщение от ValeryS Посмотреть сообщение
поскольку нет вызовов конструкторов я бы воспользовался
malloc realloc free
realloc сам перевыделит память и сам все скопирует
и перевыделял бы память не по 1 символу а допустим по 100, скорость возрастет
В задании сказано, что
Цитата Сообщение от JustForStudy Посмотреть сообщение
Память, возвращенная из функции будет освобождена оператором delete[].
Добавлено через 15 минут
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
m = new char[i]();
А зачем тут нужны скобки ?

Блин, я не понимаю... Вроде бы сделал по вашему примеру - программа все равно виснет в цикле.
Подскажите, что я снова сделал не так ?
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
#include <iostream>
using namespace std;
 
char * getline()
{
    char c = 0;
    char *m = 0, *temp = 0;
 
    int i = 2;
    
    c = cin.get();
    while (c == '\n' || c == 0) {
        m[i - 2] = c;
 
        temp = m;
        m = new char[i];
 
        for (int j = 0; j <= i - 2; j++)
            m[j] = temp[j];
        delete[] temp;
 
        i++;
        c = cin.get();
    }
 
    m[i - 1] = '\0';
 
    return m;
 
}
 
 
int main(void) {
    char *example = getline();
    for (int i = 0; i < 5; i++) {
        cout << example[i] << " ";
    }
    
    cout << endl;
 
    system("pause");
    return 0;
}
0
Эксперт PHP
3106 / 2591 / 1219
Регистрация: 14.05.2014
Сообщений: 7,236
Записей в блоге: 1
15.10.2015, 10:48 18
Цитата Сообщение от JustForStudy Посмотреть сообщение
А зачем тут нужны скобки ?
инициализация массива нулями (нуль-терминаторами в данном случае).
Цитата Сообщение от JustForStudy Посмотреть сообщение
C++
1
2
3
m[i - 2] = c;
temp = m;
m = new char[i];
прежде чем записывать символ, под него должна быть выделена память, а не наоборот.
1
1 / 1 / 0
Регистрация: 23.09.2015
Сообщений: 42
15.10.2015, 15:26  [ТС] 19
Исправил. Все равно вылетает при работе на строчке delete[] temp;

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
char * getline()
{
    char c = 0;
    char *m = 0, *temp;
 
    c = cin.get();
    int i = 3;
    m = new char(2);
    m[0] = c;
 
    while (c != '\n' || c != 0) {
 
        c = cin.get();
        m[i - 2] = c;
 
        temp = m;
        m = new char[i]();
 
        for (int j = 0; j < i - 1; j++)
            m[j] = temp[j];
 
        delete[] temp;
 
        i++;
        
    }
 
    m[i - 1] = '\0';
 
    return m;
 
}
Добавлено через 3 часа 32 минуты
Не подскажете в чем дело ?
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
15.10.2015, 17:51 20
Цитата Сообщение от JustForStudy Посмотреть сообщение
Не подскажете в чем дело ?
Да тут много чего не так.
Например вот:
Цитата Сообщение от JustForStudy Посмотреть сообщение
m = new char(2);
Это же не массив, а один символ со значением 2. Скобки для массива - квадратные.

Вот в прошлом задании у тебя было нужно реализовать resize.
Эта функция здесь нужна - сильно упростит дело. Ее специально дали первым заданием, чтобы потом можно было использовать во втором. Редкий случай, когда задания связаны и помогают, помимо обучения кодированию, еще и с подходами к разработке - в данном случае учат повторному использованию кода.
1
15.10.2015, 17:51
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.10.2015, 17:51
Помогаю со студенческими работами здесь

Третий аргумент функции sdt :: getline
Можно ли использовать в качестве третьего аргумента слово в функции std :: getline ? Если можно, то...

Отсутствуют экземпляры перегруженной функции getline
не могу решить проблему #define _CRT_SECURE_NO_WARNINGS #include &quot;stdafx.h&quot; #include &quot;conio.h&quot;...

Некорректный ввод строк с использованием функции getline
Здравствуйте столкнулся с магической проблемой функция getline(); криво работает когда вызывается...

Использование функции в своей программе из своей dll
Среда разработки Visual Studio 2008 Язык C++ Написал dll как в примере на сайте...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru