Почему чтение любого символа в целочисленную переменную с cin присваивает значение 0 переменной? [Дубликат]

$result = $data1 . $data2;

Это называется конкатенацией строк. В вашем примере не хватает места, поэтому для этого вам понадобится:

$result = $data1 . ' ' . $data2;
50
задан Some programmer dude 14 November 2012 в 14:41
поделиться

2 ответа

Из эта ссылка :

Если извлечение завершилось неудачно (например, если была введена буква, где цифра ожидается), значение остается неизмененным и устанавливается битбит ( до C ++ 11)

Если извлечение завершилось неудачно, нуль записывается в значение и устанавливается failbit. Если извлечения приводит к слишком большому или слишком маленькому значению, чтобы соответствовать значению, записывается std :: numeric_limits :: max () или std :: numeric_limits :: min () и устанавливается флаг failbit. (поскольку C ++ 11)

Кажется, что ваш компилятор компилируется в режиме C ++ 11, что изменяет поведение.


Оператор ввода использует фасет локали std::num_get , функция get вызывает do_get . Для C ++ 11 указано использование std::strtoll et. и др. тип функций. До C ++ 11 он, по-видимому, использовал std::scanf разбор стиля (по ссылке, у меня нет доступа к спецификации C ++ 03) для извлечения чисел. Изменение поведения связано с этим изменением в анализе ввода.

54
ответ дан Some programmer dude 22 August 2018 в 21:21
поделиться
  • 1
    Интересные перемены, я никогда не знал. Я всегда рассматриваю чтение переменной после неудачного извлечения как неопределенного поведения ... – Kerrek SB 14 November 2012 в 14:48
  • 2
    @KerrekSB: Я тоже. – Lightness Races in Orbit 14 November 2012 в 14:49
  • 3
    Кто-нибудь знает причину этого изменения? – Alex 14 November 2012 в 14:49
  • 4
    @Alex: Это звучит скорее в соответствии с тем, что делают strtod и т. Д. (Которые всегда возвращают определенное значение), и это дает вам некоторую информацию о том, как неудача извлечения, я полагаю. Думаю, что вне диапазона отличается от того, чтобы просто не разбираться. – Kerrek SB 14 November 2012 в 14:51
  • 5
    @Alex: Возможно облегчить реализацию функций преобразования строк ( open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1169 ). Невозможно найти, где именно это изменение формулировки было предложено. – Lightness Races in Orbit 14 November 2012 в 14:51

Оператор >> является форматированным оператором ввода. Как таковой зависит от локали для того, как ввод считывается из потока:

[istream.formatted.arithmetic]

Как и в случае вставок, эти экстракторы зависят от объекта num_get & lt;> (22.4.2.1) locale для выполнения анализа данных входного потока. Эти экстракторы ведут себя как форматированные входные функции (как описано в 27.7.2.2.1). После создания часового объекта преобразование происходит так, как если бы выполнялся следующий фрагмент кода:

   typedef num_get< charT,istreambuf_iterator<charT,traits> > numget;
   iostate err = iostate::goodbit;
   use_facet< numget >(loc).get(*this, 0, *this, err, val);
   setstate(err);

Как мы видим выше, значение фактически задается гранью numget

num_get виртуальные функции [facet.num.get.virtuals]

Этап 3:

Числовое значение для может быть одним из:

  • ноль, если функция преобразования не может преобразовать все поле. ios_base :: failbit присваивается err.
  • самое положительное представимое значение, если поле представляет слишком большое положительное значение, которое должно быть представлено в val. ios_base :: failbit присваивается err.
  • самое отрицательное представимое значение или ноль для целых чисел без знака, если поле представляет слишком большое отрицательное значение, которое должно быть представлено в val. ios_base :: failbit присваивается err.

Определение этапа 3 резко изменилось между n2723 -> n2798

Где я могу найти текущие стандартные документы C или C ++

виртуальные функции num_get [facet.num.get.virtuals]

Этап 3: результат обработки этапа 2 может быть одним из:

  • На этапе 2 была скопирована последовательность символов, которая преобразуется (согласно правилам scanf) в значение типа val. Это значение хранится в val и ios_base :: goodbit хранится в err.
  • Последовательность символов, накопленных на этапе 2, заставила scanf сообщать о сбое ввода. ios_base :: failbit присваивается ошибке.
4
ответ дан Community 22 August 2018 в 21:21
поделиться