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

Массивы неизвестной длины

22.02.2021, 23:24. Показов 4291. Ответов 16

Студворк — интернет-сервис помощи студентам
Пользователь вводит сколь угодно длинное число размер числа неизвестен нужно каждую цифру числа загнать в массив
Не понимаю даже с какого конца взяться до векторов и прочие не дошли
Предполагал использовать строку и getche но что-то ничего не получается
Вопрос. Как сделать ввод пользователем строки неизвестного размера
Считать размер, разбить строку и данные загнать в массив?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.02.2021, 23:24
Ответы с готовыми решениями:

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

Чтение строки неизвестной длины
реализация на СИ как прочитать строку неизвестной длины? Чтение должно быть не посимвольным. Строка вводиться вручную.

Считывание массива неизвестной длины
Имеется набор чисел. Про их количество ничего заранее неизвестно, кроме того, что оно кратно 10. Можно ли как-то сделать прерывание ввода...

16
Мозгоправ
 Аватар для L0M
1745 / 1039 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
22.02.2021, 23:40
solvo23, страдания на тему realloc()?
0
Заблокирован
22.02.2021, 23:47
L0M, наверное попроще ...
Cчитывайте строку,
http://www.cplusplus.com/refer... m/getline/
проверяйте что там цифры и заносите в массив.

Добавлено через 4 минуты
Цитата Сообщение от solvo23 Посмотреть сообщение
Считать размер, пройтись по строке разбить строку и данные загнать в массив?
если полагать что там только цифры (без проверки), то именно так.
1
Мозгоправ
 Аватар для L0M
1745 / 1039 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
23.02.2021, 00:05
SmallEvil, для getline() необходимо сначала выделить память под массив-приёмник. Если изначально размер этого массива неизвестен, то тут и начинаются пляски с начальным выделением некоего фиксированного объёма памяти и дальнейшим его расширением через realloc(). Соответственно, getline() тут уже не прокатывает. Читать из входного потока придётся посимвольно.
1
2 / 2 / 0
Регистрация: 05.02.2021
Сообщений: 162
23.02.2021, 00:25  [ТС]
на этом и застрял считать из строки уж можно
а вот как дать пользователю инициализировать строку НЕИЗВЕСТНОЙ длинны
0
Мозгоправ
 Аватар для L0M
1745 / 1039 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
23.02.2021, 00:41
Цитата Сообщение от solvo23 Посмотреть сообщение
на этом и застрял
Так я вам вроде написал... Не?
0
2 / 2 / 0
Регистрация: 05.02.2021
Сообщений: 162
23.02.2021, 01:09  [ТС]
Сработало!!!
C++
1
2
string name;
getline(cin, name);
Но возник следующий вопрос как проверить что пользователь вводит данные корректно
Можно конечно вычислить длину массива и простым перебором проверить
Но можно ли сделать это еще при вводе пользователем
0
Заблокирован
23.02.2021, 01:56
L0M, я согласен.
Но для учебных заданий выделенный массив большей длинны не особо критичен.
Можно взять за начальный размер массива - размер буфера cin (по логике больше строку не введет).
А если уж станет вопрос про оптимизацию по памяти - тогда
Цитата Сообщение от L0M Посмотреть сообщение
страдания на тему realloc()?
или что то в этом роде ...
0
90 / 109 / 15
Регистрация: 26.01.2014
Сообщений: 710
23.02.2021, 02:10
Ну например побайтовое чтение. Переменная чтения - байт. Начальный зарезервированный объем памяти (массив) - байт. Переменная чтения = EOF, переписываю ее в блок памяти и заканчиваю. Не EOF - переписываю переменную чтения в конец выделенного массива. Читаю в переменную чтения следующий байт извне. Резервирую следующий блок памяти на байт больше имеющегося. Копирую старый блок в новый. Старый освобождаю. В новом есть в конце свободный байт для результата второго чтения. Переписываю переменную чтения в конец блока памяти. Если EOF закругляюсь. Если не EOF - продолжаю в том же духе. Отдельно тащится счетчик числа чтоний, он же длина твоего массива.
Возможно это не оптимально, но оно работало. Память расходуется линейно по мере чтения. Читай, пока система будет выдавать тебе новую память.
Если читаешь не побайтно, выделяй память своим размером блока. Переменная чтония тоже соотвентствующего размера. И заказывай новый кусок памяти больше на очередной блок. Подумай что будет в памяти если очередная переменная чтония будет заполнена не до конца. Я читал байтами и проблем не возникало.
Твой Etien.
1
Мозгоправ
 Аватар для L0M
1745 / 1039 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
23.02.2021, 02:14
solvo23, интересно, вы написали, что
Цитата Сообщение от solvo23 Посмотреть сообщение
до векторов и прочие не дошли
А до string дошли? Чем string принципиально отличается от vector?
Если можете string, то всё тривиально.
Цитата Сообщение от solvo23 Посмотреть сообщение
Но возник следующий вопрос как проверить что пользователь вводит данные корректно
<...>
Но можно ли сделать это еще при вводе пользователем
Можно (нужно ли?).
Читайте пользовательский ввод в цикле посимвольно. Если символ корректный, добавляйте к строке.
0
Заблокирован
23.02.2021, 02:32
solvo23, пример как можно сделать то что вам нужно, не учитывая выделения, перевыделения памяти.

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
#include <iostream>
#include <sstream>
 
int main()
{
    //  std::istringstream cin("12345");
    std::istringstream cin("0012345fdsag");
    // std::istringstream cin("ddd00012345");
    const size_t buf_size = 1024;
    char digits[buf_size];
    size_t act_size=0;
    char ch;
    while(cin>>ch && isdigit(ch) && ch=='0'); // !!! игнорируем незначащие нули
    cin.putback(ch);  // возвращаем символ назад
    while(cin>>ch && act_size<buf_size)
    {
        if (isdigit(ch))
            digits[act_size++] = ch-'0';
        else
            break;
    }
    for(size_t i = 0; i<act_size; ++i)
        std::cout << static_cast<int>(digits[i]) << ' ';
}
1
Мозгоправ
 Аватар для L0M
1745 / 1039 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
23.02.2021, 03:40
Etien, можно, конечно, и так сделать. Но, во-первых, не надо завязываться на байт. А если там Юникод? А во-вторых, после чтения каждого символа перераспределять память - не лучшая идея. Это дорогая операция. Поэтому обычно в начале выделяют память не под один символ, а, допустим, сразу под 128 символов (это, по сравнению с вашим алгоритмом, сразу экономит 254 обращения к менеджеру памяти и 127 копирований массива при длине вводимой строки 128 символов). Когда выделенный блок заполнен, только тогда выделяется блок большего размера, в который копируются уже введённые символы. Какого размера должен быть новый блок? Есть разные стратегии: линейная - каждый раз блок увеличивается на константную величину, например, на те же 128; экспоненциальная - размер блока умножается на некую константу, например на 2; и т.п. Перевыделение блока памяти лучше отдать на откуп функции realloc(): она сама выделит новый блок памяти, скопирует данные и освободит старый блок.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12925 / 6793 / 1819
Регистрация: 18.10.2014
Сообщений: 17,190
23.02.2021, 03:47
Цитата Сообщение от L0M Посмотреть сообщение
А во-вторых, после чтения каждого символа перераспределять память - не лучшая идея. Это дорогая операция.
Это верно. Но не стоит также забывать про грануляцию. Стандартные функции выделения памяти, как правило, уже внутренне выравнивают размер на какую-то границу. В современных 64-битных реализациях этот как правило 16. Это означает, что даже если вы будете вызывать realloc для каждого индивидуального символа, 15 вызовов из 16 будут мгновенными и бесплатными, без какого-либо перераспределения памяти.

В общем случае, конечно, ожидать такого удобного поведения не следует.
0
Модератор
Эксперт CЭксперт С++
 Аватар для Volga_
5208 / 2925 / 1509
Регистрация: 14.12.2018
Сообщений: 5,266
Записей в блоге: 1
23.02.2021, 11:14
Лучший ответ Сообщение было отмечено solvo23 как решение

Решение

Цитата Сообщение от solvo23 Посмотреть сообщение
Вопрос. Как сделать ввод пользователем строки неизвестного размера
Считать размер, разбить строку и данные загнать в массив?
Если я понимаю этот вопрос можно попробуйте:
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
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
 
int main()
{
    string num;
    cout << "Введите число: ";
    cin >> num;
    
    int len = num.length();
    int i, dem = 0;
    for (i = 0; i < len; i++)
        if (isdigit(num[i]))
            dem = dem + 1;
 
    if (dem)
    {
        int k = 0;
        int* arr = new int[dem];
        for (i = 0; i < len; i++)
            if (isdigit(num[i]))
            {
                arr[k] = num[i]-'0';
                k = k + 1;
            }
             
        // Дальше делать нужные коды здесь
        // .......
 
        cout << "Массив с каждой цифрой из данного числа будет:" << endl;
        for (i = 0; i < dem; i++)
            cout << "arr[" << i + 1 << "] = " << arr[i] << endl;
 
        delete[] arr;
    }
    system("PAUSE");
    return 0;
}
1
90 / 109 / 15
Регистрация: 26.01.2014
Сообщений: 710
23.02.2021, 14:01
С соображениями согласен. Когда решал эту задачку нужно было читать в память обычный текст произвольной длины. Текст байтовый. Про блоки больше байта выделения памяти я упоминал. Наверное при чтении битового потока так оно может быть лучше. Так же согласен - упоминал - что сей процесс не оптимален. Но задачу он решил.
Еще раз - критика осмыслена и справедлива. Благодарю. Что можете предложить Вы вместо?
Ваш - Etien.

Добавлено через 6 минут
Можно оптимизировать в алгоритме много чего. Гнуть под особенности текста, системы, даже железа. Я предложил идею, которая задачу принципиально решает. Не оптимально. Если хотите - это не решение, а информация для размышления.
Интересно посмотреть какую другую идею, задачу решающую. Пусть тоже не оптимально.
Ваш Etien.
0
2 / 2 / 0
Регистрация: 05.02.2021
Сообщений: 162
23.02.2021, 16:52  [ТС]
Блин просто и очевидно
Почему-то всегда пытаюсь усложнить задачу, про простые вещи забываю
0
Модератор
Эксперт CЭксперт С++
 Аватар для Volga_
5208 / 2925 / 1509
Регистрация: 14.12.2018
Сообщений: 5,266
Записей в блоге: 1
23.02.2021, 16:59
Цитата Сообщение от solvo23 Посмотреть сообщение
Почему-то всегда пытаюсь усложнить задачу, про простые вещи забываю
Ближе к программисту так, спокойно !
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.02.2021, 16:59
Помогаю со студенческими работами здесь

Массив символов неизвестной длины
Добрый утро/день/вечер. Дело такое: вводится строка состоящая из слов и чисел(целых), разделяют все это безобразие разнообразные символы:...

Ввод динамического массива неизвестной длины
Нужно создать динамический массив целых чисел, размер которого неизвестен, а каждое введенное число должно сразу помещатьмя в массив,...

Ввод массива заранее неизвестной длины
#include &lt;iostream&gt; using namespace std; int main () { int n; // ввод неизвестного массива int*mass = new int ; for (int i...

Создание массива чисел неизвестной длины
Нужно сделать программу, которая считывает неизвестное наперёд количество чисел в массив. То есть чтобы можно было вводить любое количество...

Ввод массива заранее неизвестной длины
#include &lt;iostream&gt; #include &lt;math.h&gt; using namespace std; int main() { int arr, a = 0; cout &lt;&lt; &quot;Вводите...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение/ Перевод https:/ / **********/ gallery/ thinkpad-x220-tablet-porn-gzoEAjs . . .
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
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru