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

Scanf() для строки любого размера

14.09.2015, 20:44. Показов 7336. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Проблема следующая: нужно реализовать ввод и вывод с клавиатуры текста при помощи функций scanf() и printf(). Я знаю как это сделать с помощью предварительно заданного массива, но программа тогда получается неуниверсальной. То есть мне нужно, чтобы я мог ввести сколько угодно символов и при этом оптимально расходовать память. Но без предварительного введения длинны строки(дин. массив), чтобы это определялось уже введенным текстом. Заранее спасибо!

Мои наработки:
C++
1
2
3
4
5
6
7
8
9
10
void inputOutput()
{
    char text[1000]; // неоптимально, какой выход?
 
    system("cls");
    printf("Put your text:\n");
    fflush(stdin);
    scanf("%[^\n]s", text);
    printf("\nRezult: \n%s\n", text);
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.09.2015, 20:44
Ответы с готовыми решениями:

Как создать приложение для любого размера экрана?
При создании нового приложения в XE5 надо выбрать устройство или размер экрана. Кто-нибудь знает как создать "универсальное"...

Переписать программу для работы с матрицами любого размера
Как сделать чтоб работало с матрицами 3x3 и 4x4 и тд. const n=2; m=2; function max(a, b:integer):integer; begin if...

Код для простейшей программы деления и слияния любого файла на любое количество частей разного размера
Уважаемое сообщество!!! Необходим код для простейшей программы деления и слияния любого файла на любое количество частей разного размера....

15
Модератор
Эксперт С++
 Аватар для zss
13766 / 10960 / 6490
Регистрация: 18.12.2011
Сообщений: 29,234
14.09.2015, 21:14
C++
1
2
3
4
cout<<"Put your text:\n";
string text;
getline(cin,text);
cout<<"\nRezult:\n"<<text<< endl;
Оптимальней некуда!
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
14.09.2015, 21:18
Со scanf'ом никак. Если у тебя Си++, то см. пост #2, если Си - читай тут: https://www.cyberforum.ru/blogs/42536/blog278.html
1
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
14.09.2015, 21:19
Чем обусловлено использование scanf и сишных строк в плюсах?
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
14.09.2015, 21:21
Как недавно выяснили, сколь угодно там не вводится. 4000 примерно (Windows).
Ну а так, читать scanf()-ом посимвольно, наверное.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
14.09.2015, 21:36
Лучший ответ Сообщение было отмечено NOVOC4INE как решение

Решение

NOVOC4INE, в GNU есть расширение, которое позволяет делать так: http://www.gnu.org/software/li... Input.html
4
0 / 0 / 0
Регистрация: 14.09.2015
Сообщений: 6
14.09.2015, 21:54  [ТС]
C++
1
2
3
4
cout<<"Put your text:\n";
string text;
getline(cin,text);
cout<<"\nRezult:\n"<<text<< endl;
Оптимальней некуда!
Такой способ знаю, но по заданию мне нужно как-то обойтись одними только printf() и scanf().

Чем обусловлено использование scanf и сишных строк в плюсах?
Обусловлено заданием к лабораторной работе.

Добавлено через 11 минут
NOVOC4INE, в GNU есть расширение, которое позволяет делать так: http://www.gnu.org/software/li... Input.html
DrOffset, похоже это то, что нужно. Спасибо за помощь, сейчас попробую внедрить эту конструкцию
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
14.09.2015, 22:09
Без scanf, но почти:
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//-----------------------------------------------------------------------
//----------------------read_string_and_allocate-------------------------
//-----------------------------------------------------------------------
//Чтение строки произвольной длины из потока ввода
char * read_string_and_allocate ()
{
    int buffer_size = 64 ;//Размер буфера для чтения
    int buffer_size_divizer = 1 ; //Делитель для размера буфера. Изначально равен 1, далее станет понятно почему
    int offset_in_buffer = 0 ; //Смещение в буфере изначально равно нулю
    int length ;
    char * buffer = (char*)malloc ( buffer_size ) ; //Выделяем память под буфер
 
    if ( buffer == NULL ) //Если не удалось выделить, то
    {
        return NULL ; //Возвращаем ноль
    }
    buffer[0] = '\0' ;
    //Цикл до тех пор, пока не считаем всю строку целиком в буфер
    while ( 1 )
    {
        //Считываем строку из потока ввода
        //Причем считываем в буфер, со смещением равным offset_in_buffer
        //В качестве размера буфера передаем отношение размера буфера к делителю(buffer_size_divizer)
        if ( fgets( buffer + offset_in_buffer , buffer_size/buffer_size_divizer , stdin ) == NULL )
        {
            //Если нарвались на ошибку чтения, то выводим сообщение об ошибке
            printf ("\nRead error. Please, try again\n") ;
            fflush(stdout) ;//сбрасываем поток вывода
            fscanf ( stdin , "%*[^\n]" ) ; //Считываем символы, оставшиеся в потоке ввода
            free (buffer) ;//Освобождаем память, занятую буфером
            return NULL ; //Возвращаем ноль
        }
        else //Если прочитали успешно, то
        {
            //Вычисляем размер считанной строки (не считая '\0') и не считая ранее считанных символов (это контролируется смещением)
            length = strlen (buffer+offset_in_buffer) ;
            if ( buffer[length-1+offset_in_buffer] != '\n' ) //Если последний символ в строке (опять же, смещение контролирует начало отсчета, чтобы не считать уже считанные ранее символы) не равен '\n' ,
            //значит считали еще не все символы из потока
            {
                //Увеличиваем размер буфера равным в два раза больше текущего
                buffer_size *= 2 ;
                char * buffer_temp = buffer ;//Сохраняем указатель на буфер, чтобы в случае ошибки освободить память
                //Перевыделяем память нового размера
                //realloc сам скопирует старые даные в новую память
                buffer = (char*)realloc ( buffer , buffer_size ) ;
                if ( buffer == NULL ) //Если память выделить не удалось, то
                {
                    free ( buffer_temp ) ; //Освобождаем память
                    return NULL ; //вернем 0
                }
                //Теперь у нас доступна только половина буфера
                //ведь в первой половине буфера у нас находятся символы
                //уже считанные ранее, поэтому
 
                //К текущему смещению прибавляем длину строки, это
                //позволит потом считывать строку дальше в буфер со смещением, не задевая уже считанные символы
                offset_in_buffer += length ;
                //Устанавливаем делитель для размера буфера
                //это укажет, что теперь нам доступен не весь размер буфера, а лишь половина
                buffer_size_divizer = 2 ;
                //в результате это приведет к чтению только во вторую половину буфера без переполнения
            }
            else //Если же последний считанный символ равен '\n', то
            {
 
                buffer[length-1+offset_in_buffer] = '\0' ; //Заменяем символ конца строки на символ '\0'
                break ;//и выходим из цикла
            }
        }
    }
    return buffer ; //Возвращаем указатель на буфер со строкой
}

P.S. Писал давно, если есть предложения по улучшению - в студию
2
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
14.09.2015, 23:00
Цитата Сообщение от NOVOC4INE Посмотреть сообщение
DrOffset, похоже это то, что нужно. Спасибо за помощь, сейчас попробую внедрить эту конструкцию
Маловероятно, что целью задания было раскопать нестандартное расширение scanf'а

Цитата Сообщение от Croessmah Посмотреть сообщение
Без scanf, но почти
По сути это ж то же самое, что и в статье fasked
0
0 / 0 / 0
Регистрация: 14.09.2015
Сообщений: 6
14.09.2015, 23:16  [ТС]
Цитата Сообщение от Evg Посмотреть сообщение
Маловероятно, что целью задания было раскопать нестандартное расширение scanf'а



По сути это ж то же самое, что и в статье fasked
Я просто не вижу другого решения этой проблемы для себя, кроме как использовать что-то нестандартное.
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
14.09.2015, 23:26
Цитата Сообщение от Evg Посмотреть сообщение
По сути это ж то же самое, что и в статье fasked
помню, на его основе и делал, только добавил перевыделение памяти
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
14.09.2015, 23:32
Цитата Сообщение от NOVOC4INE Посмотреть сообщение
Я просто не вижу другого решения этой проблемы для себя, кроме как использовать что-то нестандартное
Я просто реальной проблемы не понимаю. Если нужно обязательно использовать scanf, то такая постановка задачи может быть только учебная, а потому использование расширения scanf'а тут как-то неуместно. Другой необходимости в использовании именно scanf'а в голову попросту не приходит

Добавлено через 4 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение
помню, на его основе и делал, только добавил перевыделение памяти
Действительно, я и забыл, что его вариант без перевыделения. Добавил туда ссылку на твою реализацию. Если вдруг он объявится на форуме, может в статью добавит
1
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
14.09.2015, 23:37
Цитата Сообщение от Evg Посмотреть сообщение
Другой необходимости в использовании именно scanf'а в голову попросту не приходит
ну мне как-то пришлось использовать для чтения логов. Читать из файла fstream'ом, а потом парсить получалось медленно и не поворотливо, с функцией scanf всё стало просто и замечательно, и процесс обработки логов стал очень быстрым правда, тогда я много не знал, делал как умею
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
14.09.2015, 23:44
Но у тебя не стояла задача как "обязательно использовать scanf". Да и для чтения логов вполне можно обойтись буфером статического размера
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
14.09.2015, 23:50
Цитата Сообщение от Evg Посмотреть сообщение
Да и для чтения логов вполне можно обойтись буфером статического размера
Да, именно так и делал. Длина строк в каждом логе отличалась, но максимальная не превышала 77 символов, поэтому сделал буфер на стеке.
Цитата Сообщение от Evg Посмотреть сообщение
Но у тебя не стояла задача как "обязательно использовать scanf"
Нет, не стояла, но на тот момент scanf (точнее fscanf) оказался для меня лучшим выбором может и у ТС подобная ситуация - надо сделать, но другие средства не доступны из-за незнания

Добавлено через 32 секунды
Хотя нет, вру
Цитата Сообщение от NOVOC4INE Посмотреть сообщение
Обусловлено заданием к лабораторной работе.
0
0 / 0 / 0
Регистрация: 14.09.2015
Сообщений: 6
15.09.2015, 00:32  [ТС]
Цитата Сообщение от Evg Посмотреть сообщение
Я просто реальной проблемы не понимаю. Если нужно обязательно использовать scanf, то такая постановка задачи может быть только учебная, а потому использование расширения scanf'а тут как-то неуместно. Другой необходимости в использовании именно scanf'а в голову попросту не приходит
Возможно, Вы правы. Наверное, попробую сдать лабораторную в таком виде, как есть сейчас, то есть со статическим массивом символов. Спасибо за помощь
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.09.2015, 00:32
Помогаю со студенческими работами здесь

Вычислить определитель матрицы любого размера
Необходимо вычислить определитель матрицы любого размера

Шрифт любого размера воспроизводится одинаково
В Ворде 2003 устанавливал защиту паралем на открытие файла и, вероятно, что-то перемудрил с настройками. Теперь шрифт любого размера...

как Считать файл любого размера??
Собственно вопрос в теме, пытался считывать файл побайтно, но получилось очень долго файл мп3 весом в 6 метров читал минут этак с сорок?? ...

Не получается сделать форму любого размера
Мой код: uses System.Windows.Forms begin var f1:=new form(); f1.Width:=10; f1.Height:=10; ...

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


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
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
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru