Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
VanyakaCompany
3 / 2 / 2
Регистрация: 15.07.2014
Сообщений: 77
#1

Различия между scanf("%s") и gets() - C++

01.06.2016, 11:13. Просмотров 859. Ответов 6

На сколько я знаю, scanf("%s") считывает до первого пробела, а gets() до первого переноса строки.

Недавно заметил такую вещь: gets(), в отличии от scanf("%s"), начинает записывать сразу в 1 строку, при этом нагло пропуская 0.
Я, конечно, нашёл решение - начинать цикл с "-1" ,
но, всё же, интересно узнать: с чем это связано?

Вот код, в котором сравнивается работа двух этих функций:
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
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <string.h>
#include <cstdlib>
 
using namespace std;
 
char text1[20][81];
char text2[20][81];
int M;
 
int _tmain(int argc, _TCHAR* argv[])
{
 
    setlocale(0, "");
 
    printf("Введите кол-во строк:\n");
    scanf("%d", &M);
 
    printf("\nВведите текст1:\n");
    for(int i = 0; i < M; i++)
    {
        scanf("%s", text1[i]);
    }
 
    printf("\nВведите текст2:\n");
    for(int i = 0; i < M; i++)
    {
        gets(text2[i]);
    }
 
    printf("\nВаш текст1:\n");
    for(int i = 0; i <  M; i++)
    {
        printf("_ %s\n", text1[i]);
    }
 
    printf("\nВаш текст2:\n");
    for(int i = 0; i <  M; i++)
    {
        printf("_ %s\n", text2[i]);
    }
 
    system("pause");
    return 0;
}
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.06.2016, 11:13
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Различия между scanf("%s") и gets() (C++):

Различия между "пробелы" и "табуляция" - C++
Есть две статьи на хабре: в пользу табуляции и против я вообще не пойму сути проблемы: вот пишу я код, нужно на следущую строку -...

scanf (какие различия между %f %g %e) - C++
Есть вопрос по функции scanf, а именно про спецификации формата. %f - читает число с плавающей точкой. %g - читает число с плавающей...

"cin","cout" на "printf","scanf" - C++
Вот ещё прога. Мне чисто нужно переделать её на printf,scanf и не используя функцию show, а puts и gets. #include &lt;iostream&gt; using...

Как сделать так, чтобы scanf в переменную double мог считывать с клавиатуры не только "0,01", но и "0.01" - C++
Помогите!) Не знаю, искал, не нашел, возможно ли вообще. Чтобы и так и так понимал.

Создать классы "Computer", "Software", "User" и реализовать взаимодействие объектов этих типов между собой - C++
Помогите решить задачку,нужна в инст на экзамен. Составить программу реализующую: 1)классы,которые могут содержать...

В зависимости от времени года "весна", "лето", "осень", "зима" определить погоду "тепло", "жарко", "холодно", "очень холодно" - C++
В зависимости от времени года &quot;весна&quot;, &quot;лето&quot;, &quot;осень&quot;, &quot;зима&quot; определить погоду &quot;тепло&quot;, &quot;жарко&quot;, &quot;холодно&quot;, &quot;очень холодно&quot;. Я так...

6
Kotik_leapold
73 / 68 / 48
Регистрация: 18.12.2015
Сообщений: 399
01.06.2016, 11:31 #2
Привет, основное отличие:
scanf () заканчивается принимать ввод при встрече с пробелами, символом новой строки или EOF.

gets() рассматривает пробелы как часть входной строки и заканчивается ввод при встрече с новой строки или EOF.

Однако, чтобы избежать ошибок переполнения буфера и избежать угроз безопасности, его безопаснее использовать fgets ()
0
Humpty
14 / 14 / 5
Регистрация: 10.03.2016
Сообщений: 35
01.06.2016, 11:32 #3
scanf не читает пробельные символы в конце строки. Первое, что видит gets -- '\n', и функция возвращает пустую строку.
0
VanyakaCompany
3 / 2 / 2
Регистрация: 15.07.2014
Сообщений: 77
01.06.2016, 11:38  [ТС] #4
А откуда он считывает этот '\n' , ведь я только начинаю вводить строки?

И не приведёт ли к ошибке, если я буду начинать ввод через gets() с (-1) строки?
0
Humpty
14 / 14 / 5
Регистрация: 10.03.2016
Сообщений: 35
01.06.2016, 11:46 #5
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Это для вас только начинается ввод новой строки, а для компьютера есть два разных потока ввода и вывода. В консоли они перемешаны, но в модели раздельны. Когда вы закончили вводит часть со scanf, в конце повис символ \n. Его gets и читает.

В целом лучше не мешать различные типы ввода/вывода. А в отношении gets использовать fgets. Он безопаснее. Можно хотя бы указать максимальный размер буффера.

Про ошибку не знаю. Вы обращаетесь к text2[-1]. Valgrind на такое, наверное, будет ругаться. А упадет ли программа, я не знаю. Скорее всего здесь будет unpredicted behavior.
1
VanyakaCompany
3 / 2 / 2
Регистрация: 15.07.2014
Сообщений: 77
01.06.2016, 11:53  [ТС] #6
Большое спасибо, всё понятно объяснил.

А решение нашёл:
C++
1
2
3
4
5
6
7
gets(text[0]);
 
    printf("\nВведите текст:\n");
    for(int i = 0; i < M; i++)
    {
        gets(text[i]);
    }
0
Humpty
14 / 14 / 5
Регистрация: 10.03.2016
Сообщений: 35
01.06.2016, 12:04 #7
Ага, так лучше. Только еще бывают такие неприятные вещи, что в некоторых системах в конце строки стоит \r\n. gets на них может затупить. Если это критично, я бы scanf немного изменил:
C++
1
2
char dummy[256];
scanf("%s%[\n\r\t ]", text1[i], dummy);
%[\n\r\t ] как раз прочитает пробельные символы в буффер dummy.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.06.2016, 12:04
Привет! Вот еще темы с ответами:

Расставить между числами знаки "+" и "-" так, чтобы значение выражение стало равно S - C++
Даны N целых чисел X1, X2, ..., XN. Расставить между ними знаки &quot;+&quot; и &quot;-&quot; так, чтобы значение получившегося выражения было равно заданному...

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

Создание объекта класса сразу после его описания (между "}" и ";") - C++
Пишу проект с дюжиной хедеров и десятком cpp-шников. Мне нужны пара объектов класса А, которые должны существовать на протяжении всей...

Реализовать классы "Воин", "Пехотинец", "Винтовка", "Матрос", "Кортик" (наследование) - C++
Разработать программу с использованием наследования классов, реализующую классы: − воин; − пехотинец(винтовка); − матрос(кортик). ...


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

Или воспользуйтесь поиском по форуму:
7
Yandex
Объявления
01.06.2016, 12:04
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru