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

Динамическое выделение памяти под строки в стиле Си

01.01.2016, 15:33. Показов 10213. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
В программе пользователь вводит строку неизвестного заранее размера. Ее нужно передать в функцию для работы с ней. Как это оформить на c++?
Функция должна быть вида
C++ (Qt)
1
FuncName(char *s)
И как ее вызывать в main?

C
1
2
3
4
5
char *ss;
ss = (char *)malloc(n * sizeof(char));
scanf("%s",&ss);
 
FuncName(&ss);
Если использовать malloc, то надо знать кол-во символов по идее. Вообще конструкцию с malloc я взял готовую и не понимаю, как она работает.

При таком
C
1
FuncName(&ss);
использовании функции в мэйне выдает ошибку о несовместимости, а если сделать так
C
1
FuncName(ss)
, то происходит ошибка чтения строки внутри функции
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.01.2016, 15:33
Ответы с готовыми решениями:

Динамическое выделение памяти под строки
Доброго времени суток. Изучаю основы C++, дошел до раздела "указатели и динамическое выделение...

Динамическое выделение памяти под объект
Здравствуйте, меня интересует несколько вопросов по поводу конструкции new. Есть такой код: ...

Динамическое выделение памяти под массив
Доброго времени! Требуется ввести размер массива с клав-ры, заполнить массив - изменить его размер...

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

15
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
01.01.2016, 15:47 2
Цитата Сообщение от Alex31115 Посмотреть сообщение
В программе пользователь вводит строку неизвестного заранее размера. Ее нужно передать в функцию для работы с ней. Как это оформить на c++?
Если на C++, то void func(const std::string&str).
Если через char*, то размер строки определяется положением нулевого (0/'\0') символа. Где он встретился, там и конец, все что после него игнорируется.
1
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
01.01.2016, 15:48 3
Несколько слов о чтении данных с консоли и языке Си
Scanf() для строки любого размера
1
1 / 1 / 0
Регистрация: 03.11.2015
Сообщений: 41
01.01.2016, 16:33  [ТС] 4
Пробую создать так,

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
int i=0;
    char *ss;
    int b = 0;
    int c = 0;
    scanf("%s", &ss);
    while (*ss[i]!="\0")
    {           
        i++;
    }
 
    char *ss = new stroka((i + 1)* sizeof(char));
но компилятор выдает ошибку "Операнд * должен быть указателем". Так он и есть указатель, объявленный как
C++ (Qt)
1
char *ss;
Как это поправить?
0
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
01.01.2016, 16:42 5
Цитата Сообщение от Alex31115 Посмотреть сообщение
Так он и есть указатель
&ss - указатель на указатель.
Цитата Сообщение от Alex31115 Посмотреть сообщение
Как это поправить?
Никак - scanf не умеет читать строки переменной длины, автоматически выделяя под них память и сохраняя указатель на эту память в операнд. Вот cin умеет, но только если читать в std::string.
1
1 / 1 / 0
Регистрация: 03.11.2015
Сообщений: 41
02.01.2016, 10:45  [ТС] 6
Подскажите, как сделать, чтобы строка произвольной длины, введенная с клавиатуры в мэйне,
передавалась в функцию с прототипом
C++ (Qt)
1
void FName(char  *s, int  *b, int  *c)
Как я понимаю *s это разыменованный указатель на переменную строкового типа, значит в главной программе тоже должен быть такой указатель, для вызова функции, и надо, чтобы он указывал на введенную пользователем строку. То есть код примерно такой
C++ (Qt)
1
2
3
4
5
6
int main()
{char UserString[];
cin<<UserString;
char *ss;
ss = &UserString; 
FName(*ss,&bb,&cc);}
И получается внутри функции мы будем работать со строкой например так
C++ (Qt)
1
if (*s[i]=10) {cout<<"вот так";}
Но строка без размера, как уже писали в теме не вводится, если только использовать
cin на тип string;
Короче, можно ли как то выполнить условия задачи?
0
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
02.01.2016, 11:05 7
Цитата Сообщение от Alex31115 Посмотреть сообщение
Как я понимаю *s это разыменованный указатель на переменную строкового типа
Нет, * - часть типа s (char*). Хотя, char* s,m; объявляет две переменные разного типа. Причины теряются в веках и возможно связаны с тем, что авторы Си курили что-то запретное.
Строкового же типа в стиле Си просто не существует. Есть только массив char, на который и указывает s.
1
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
02.01.2016, 16:21 8
Цитата Сообщение от Alex31115 Посмотреть сообщение
Как это оформить на c++?
Вы таки с языком программирования определитесь. В С++ для этого есть класс std::string, в С нужно или свой динамически расширяющийся массив писать, или использовать готовые решения вроде String из Glib:
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
#include <stdio.h>
#include <glib.h>
 
char * get_string(FILE * inp, gboolean includeNL) {
    int c;
    GString * s = g_string_new("");
    
    while ( ( c = fgetc(inp) ) != EOF ) {
        if ( c == '\n' ) {
            if ( includeNL )
                s = g_string_append_c(s, (gchar)c);
            break;
        }
        s = g_string_append_c(s, (gchar)c);
    }
    
    return g_string_free(s, FALSE);
}
 
int main(void) {
    char * str;
    
    while ( printf("> ") && ( str = get_string(stdin, FALSE) ) && *str ) {
        printf(": %s\n", str);
        g_free(str);
    }
    
    return 0;
}
Код
~/cpp/glib $ gcc get_string.c `pkg-config --cflags --libs glib-2.0`
~/cpp/glib $ ./a.out 
> any
: any
> many
: many
> money
: money
> more
: more
> 
~/cpp/glib $
1
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
02.01.2016, 17:08 9
Цитата Сообщение от easybudda Посмотреть сообщение
Вы таки с языком программирования определитесь.
так оно изначально в разделе c++ и было.
1
1 / 1 / 0
Регистрация: 03.11.2015
Сообщений: 41
06.01.2016, 11:59  [ТС] 10
Да, это с++.
А что вот с этим можно поделать. Ошибка на начале обхода строки при
C++ (Qt)
1
i=0
уже не читается
C++ (Qt)
1
s[i]
.

Скриншот с ошибкой во вложении.

Текст программы
C++ (Qt)
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
#include "stdafx.h"
#include <iostream>
#include "stdlib.h"
#include "stdio.h"
using namespace std;
 
 
void  function_name(char  *s, int  *bukv, int  *cifr)
{
    int i=0;
    while (s[i] != '\0')
    {
        if ((s[i] == '0') || (s[i] == '1') || (s[i] == '2') || (s[i] == '3') || (s[i] == '4') || (s[i] == '5') || (s[i] == '6') || (s[i] == '7') || (s[i] == '8') || (s[i] == '9'))
        {
            *cifr++;
        }
        else
        {
            *bukv++;
        }
        i++;
    }
    cout << *bukv, "  ", *cifr;
   
}
 
int main()
{   
    char* s;
    scanf(" %s", &s);
    int b = 0, c = 0;
 
    function_name(s, &b, &c);
 
 
    system("Pause");
    return 0;
}
Миниатюры
Динамическое выделение памяти под строки в стиле Си  
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
06.01.2016, 15:01 11
Цитата Сообщение от Alex31115 Посмотреть сообщение
Да, это с++.
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <cstdio>
#include <string>
 
int main() {
    std::string s;
    
    while ( std::cout << "> " && std::getline(std::cin, s) && ! s.empty() )
        printf("%s\n", s.c_str()); //ничего лучше не придумалось
        
    return 0;
}
это, если нужен указатель на константную строку в С-стиле. Если нужна С-строка, которую можно изменять (интересно, зачем оно в С++?), ну создайте буфер в длину строки + 1 символ и скопируйте в него то, что c_str() возвращает.

 Комментарий модератора 
Вернул тему из раздела "С для начинающих"


Добавлено через 30 минут
Alex31115, и кстати, если уж у'чите С++, так и учи'те С++! К чему странные велосипеды в С-стиле?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>
 
int main() {
    std::string s;
    
    while ( std::cout << "String: " && std::getline(std::cin, s) && ! s.empty() ) 
        std::cout << std::count_if(s.begin(), s.end(), isalpha) << " letters\n" 
                << std::count_if(s.begin(), s.end(), isdigit) << " digits" << std::endl;
    
    return 0;
}
3
1 / 1 / 0
Регистрация: 03.11.2015
Сообщений: 41
06.01.2016, 19:09  [ТС] 12
Цитата Сообщение от easybudda Посмотреть сообщение
Alex31115, и кстати, если уж у'чите С++, так и учи'те С++! К чему странные велосипеды в С-стиле?
Кликните здесь для просмотра всего текста
У нас интересное преподавание. Лекции идут по C. На практике другой преподаватель и пишем мы на C++.

А почему все-таки в моей проге не читается строка? Просто нам по условию задачи нельзя использовать библиотечные строковые функции...
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
06.01.2016, 22:05 13
Цитата Сообщение от Alex31115 Посмотреть сообщение
А почему все-таки в моей проге не читается строка?
Память под неё не выделена
Цитата Сообщение от Alex31115 Посмотреть сообщение
char* s;
Значение - какое-то случайное число.
Цитата Сообщение от Alex31115 Посмотреть сообщение
scanf(" %s", &s);
куда-то в памяти пытаемся записать символы с консоли. Скорее всего грохнется с ошибкой времени выполнения.
C++
1
2
3
4
5
6
7
char s[256];
if ( scanf("%255s", s) != 1 ) {
  // ошибка, строка не прочитана
}
int n, m;
moya_adskaya_funkciya(s, &n, &m);
//...
хотябы так как-то
1
393 / 165 / 32
Регистрация: 10.12.2015
Сообщений: 717
06.01.2016, 22:18 14
Цитата Сообщение от Alex31115 Посмотреть сообщение
У нас интересное преподавание. Лекции идут по C. На практике другой преподаватель и пишем мы на C++.
Напрашивается логичный вывод: забить на лекции и заниматься плюсами самостоятельно.
0
nonedark2008
06.01.2016, 22:32
  #15

Не по теме:

Цитата Сообщение от cyber-satyr Посмотреть сообщение
Напрашивается логичный вывод: забить на лекции и заниматься плюсами самостоятельно.
А потом завалиться на экзамене, потому что "не то".

0
393 / 165 / 32
Регистрация: 10.12.2015
Сообщений: 717
06.01.2016, 22:35 16
nonedark2008, не знаю, я думал что в ВУЗ поступают для того чтобы учиться, а не ныть как в школе. Объем требований к студенту ясно вырисован с первых дней круса. Так что будь добр. Или грузчиком на рынок, если мозгов и терпения не хватает.
0
06.01.2016, 22:35
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.01.2016, 22:35
Помогаю со студенческими работами здесь

Динамическое выделение памяти под массив
Здравствуйте! Помогите разобраться.Сама программа есть, но без массива.Не могу сообразить как...

Динамическое выделение памяти под файл
Дали задание считать масив чисел с файла Ф1, сделать над ним некоторые действия и получившийся...

Динамическое выделение памяти под структуры
Есть вот такая структура: struct asd { int data; struct asd *next; };Динамически выделяю...

Динамическое выделение памяти под массив
Я хочу функцию использовать пару раз, количество команд будет уменьшаться, и &quot;n&quot; надо менять. Как...


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

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