为什么这项工作?使用CIN读取到一个字符数组超过给定的输入小 [英] Why does this work? Using cin to read to a char array smaller than given input

查看:255
本文介绍了为什么这项工作?使用CIN读取到一个字符数组超过给定的输入小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在看C ++的Primer Plus(第6版),我已经遇到了一些示例code第4章中,我有一个问题关于:

I'm reading C++ Primer Plus (6th Edition) and I've come across some sample code in chapter 4 which I have a question about:

清单4.2 strings.cpp

// strings.cpp -- storing strings in an array
#include <iostream>
#include <cstring> // for the strlen() function
int main()
{
    using namespace std;
    const int Size = 15;
    char name1[Size]; // empty array
    char name2[Size] = "C++owboy"; // initialized array
    // NOTE: some implementations may require the static keyword
    // to initialize the array name2
    cout << "Howdy! I'm " << name2;
    cout << "! What's your name?\n";
    cin >> name1;
    cout << "Well, " << name1 << ", your name has ";
    cout << strlen(name1) << " letters and is stored\n";
    cout << "in an array of " << sizeof(name1) << " bytes.\n";
    cout << "Your initial is " << name1[0] << ".\n";
    name2[3] = '\0'; // set to null character
    cout << "Here are the first 3 characters of my name: ";
    cout << name2 << endl;
    return 0;
}

在code本身不会造成任何混乱,但我一直在通过运行它,我按一定的情况下糊涂了。

The code itself doesn't cause any confusion, but I've been running it through and I'm confused by a certain scenario.

名1被初始化为字符数组15种元素的长度?结束字符应预留一个字符串结束了吧?

name1 is initialised as an array of chars 15 elements in length - am I right in thinking this should hold a string 14 characters in length? The end char should be reserved for the string terminator, right?

如果我输入我的名字 HowCanIPossiblyFitThisEntireStringIn 后,我得到以下的输出:

If I enter my name as HowCanIPossiblyFitThisEntireStringIn?, I get the following output:

您好!我是C ++ owboy!你叫什么名字?

Howdy! I'm C++owboy! What's your name?

HowCanIPossiblyFitThisEntireStringIn?

HowCanIPossiblyFitThisEntireStringIn?

好吧,HowCanIPossiblyFitThisEntireStringIn?你的名字有37个字母和存储

Well, HowCanIPossiblyFitThisEntireStringIn?, your name has 37 letters and is stored

在15个字节的阵列

您最初是H

下面是我名字的前3个字符:C ++

Here are the first 3 characters of my name: C++

如何进入我的整个名称被存储?如果我通过code步骤,CIN读入后NAME1,Visual Studio中告诉我,它包含多个元素0 - 14日,随着最后一个是字符Y(HowCanIPossibly ...)我想从这个假设。任何额外的数据输入已经被截断而失败,但这显然并非如此,因为下面的COUT成功写入整个名称到控制台。

How is the entire name I enter being stored? If I step through the code, after cin reads into name1, Visual Studio tells me it contains elements 0 - 14, with the last one being the char 'y' ("HowCanIPossibly...). I would assume from this that any extra data entered had been truncated and lost, but this is obviously not the case as the following cout successfully writes the entire name out to the console.

有关好奇心的缘故,任何人都可以赐教,以这里发生了什么?为了记录在案,我使用Visual Studio 2012中前preSS。

For curiosity's sake, could anyone enlighten me as to what's happening here? For the record, I'm using Visual Studio 2012 Express.

推荐答案

您正在写越过数组的边界。 C ++标准不说,这应该是一个错误;它说,这是不确定的行为。这意味着,任何事情都有可能发生,包括看似正常工作。简单地说,你的code没有良好定义的行为,所以你不应该相信它的工作。

You are writing past the bounds of the array. The C++ standard doesn't say this should be an error; it says it is undefined behaviour. This means anything can happen, including seemingly working correctly. Simply put, your code does not have well-defined behaviour and so you shouldn't trust it to work.

我们可以想像,为什么它可能工作虽然。前15个字符会很好地融入数组:

We can imagine why it's probably working though. The first 15 characters will fit nicely into the array:

|H|o|w|C|a|n|I|P|o|s|s|i|b|l|y|F|i|t|T|h|i|s|E|n|t|i|r|e|S|t|r|i|n|g|I|n|?|...
^                             ^
|    These characters fit     |
         in the array

字符的其余部分被写入以下存储位置。现在,请记住空字符,这是用来终止C风格的字符串,被定义为有一个重新presentation这是所有0位。现在,如果下面包含中有全0位,字符串将显示为的位置的位置空值终止。

The rest of the characters are being written to the following memory locations. Now, remember that the null character, which is used to terminate C-style strings, is defined to have a representation that is all 0 bits. Now if the location following the location that contains the ? has all 0 bits in it, the string will appear to be null-terminated.

但事实是,这是不确定的。这恰好工作。不幸的是,这是因为它可以为看似很长一段时间的工作,直到有一天你开始得到从你非常,非常生气客户端调用最可怕类型的bug。

But the fact is, this is undefined. It just happens to work. Unfortunately, this is the scariest type of bug because it can seemingly work for a long time until one day you start getting calls from your very, very angry client.

这篇关于为什么这项工作?使用CIN读取到一个字符数组超过给定的输入小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆