字符串输入/输出

时间:2018-12-31 17:00:31

标签: c++

我对编程还是有点陌生​​,所以请原谅我任何愚蠢的问题:P,我注意到当我写这篇文章时

int main()
    {
        string s;
        s[0]='a';
        cout<<s.size();
        cout<<s<<" ";
        cout<<s[0];
       return 0;
    }

输出为0 a,为什么大小为0?以及为什么在我写cout<<s;时没有打印任何内容,但给出了cout<<s[0]的含义。如果我使用push_back,它可以正常输出。

int main()
{
    string s;
    s.push_back('a');
    cout<<s.size();
    cout<<s<<" ";
    cout<<s[0];
   return 0;
}

输出:-1a a

我可能忽略了某些内容,但是如果有人可以指出原因,我将不胜感激。 谢谢。

编辑:如此快速的回复!感谢您的回答,我无法确定如何回复评论,因此编辑了问题正文(首次使用stackoverflow), (对此也有帮助),还有一件事情,所以当我使用cout<<s[0]时,它会给出a,因为a存储在字符串的下一个地址上 s? 再次感谢您清除了!

5 个答案:

答案 0 :(得分:5)

您忽略的是,在C ++中,当您给字符分配字符时,它不会自动增长。所以

string s;
s[0]='a';

是错误的,因为s的大小为零,因此字符'a'没有'room'。向字符串添加字符的正确方法是使用push_back,这就是第二个示例起作用的原因。

由于该错误,您的第一个示例具有未定义的行为(简称UB)。这意味着程序的输出根本无法预测,并且或多或少地浪费时间在询问为什么输出程序。就像崩溃一样容易。

答案 1 :(得分:4)

此:

   string s;

创建一个包含 no 个字符的字符串。然后:

  s[0]='a';

试图更改那些不存在的字符之一。结果是行为未定义-您的程序进入未知状态。

如果您想让编译器警告您此问题,可以使用字符串的at()成员函数:

  s.at(0) = 'a';

现在,当您尝试更改不存在的字符时,程序将引发std::out_of_range异常。

答案 2 :(得分:0)

容器不会自动分配存储,因此您正在分配的存储之外进行写入。换句话说,那是程序中的错误。一个建议:许多C ++实现都有一种方法可以激活调试程序的诊断程序,而这些程序可能会捕获此错误。

答案 3 :(得分:0)

  

当我写这篇文章

string s;
s[0]='a';
     

输出为0,首先为什么大小为0?

输出为零,因为operator[i]假定字符串具有足够的空间来存储i+1个字符。在您的情况下,字符串的大小为零,因此访问索引0的元素是未定义行为

  

为什么我写cout

时什么都没打印

同样的道理也适用:在未定义的行为之后,程序可以输出任何东西,但是它却什么也不输出。

答案 4 :(得分:-1)

public partial class SomeChip : UserControl
{

    public event PinPanelClick ClickedPinPanel;
    public delegate void PinPanelClick(int index, bool input);

    private PinPanel[] inputPins;
    private PinPanel[] outputPins;

    private int _NumberInputPins = 2;
    public int NumberInputPins
    {
        get {
            return _NumberInputPins;
        }
        set
        {
            if (value > 0 && value != _NumberInputPins)
            {
                _NumberInputPins = value;
                CreatePinPanels();
                this.Refresh();
            }
        }
    }

    private int _NumberOutputPins = 1;
    public int NumberOutputPins
    {
        get
        {
            return _NumberOutputPins;
        }
        set
        {
            if (value > 0 && value != _NumberOutputPins)
            {
                _NumberOutputPins = value;
                CreatePinPanels();
                this.Refresh();
            }
        }
    }

    public SomeChip()
    {
        InitializeComponent();
    }

    private void SomeChip_Load(object sender, EventArgs e)
    {
        CreatePinPanels();
        RepositionPins();
    }

    private void SomeChip_SizeChanged(object sender, EventArgs e)
    {
        this.Refresh();
    }

    private void SomeChip_Paint(object sender, PaintEventArgs e)
    {
        int PinHeight;
        // draw the input pin runs
        if (inputPins != null)
        {
            PinHeight = (int)((double)this.Height / (double)_NumberInputPins);
            for (int i = 0; i < NumberInputPins; i++)
            {
                int Y = (i * PinHeight) + (PinHeight / 2);
                e.Graphics.DrawLine(Pens.Black, 0, Y, this.Width / 4, Y);
            }
        }
        // draw the output pin runs
        if (outputPins != null)
        {
            PinHeight = (int)((double)this.Height / (double)_NumberOutputPins);
            for (int i = 0; i < NumberOutputPins; i++)
            {
                int Y = (i * PinHeight) + (PinHeight / 2);
                e.Graphics.DrawLine(Pens.Black, this.Width - this.Width / 4, Y, this.Width, Y);
            }
        }
        //draw the chip itself (takes up 50% of the width of the UserControl)
        Rectangle rc = new Rectangle(new Point(this.Width / 4, 0), new Size(this.Width / 2, this.Height - 1));
        using (SolidBrush sb = new SolidBrush(this.BackColor))
        {
            e.Graphics.FillRectangle(sb, rc);
        }
        e.Graphics.DrawRectangle(Pens.Black, rc);
        RepositionPins();
    }

    private void CreatePinPanels()
    {
        if (inputPins != null)
        {
            for (int i = 0; i < inputPins.Length; i++)
            {
                if (inputPins[i] != null && !inputPins[i].IsDisposed)
                {
                    inputPins[i].Dispose();
                }
            }
        }
        inputPins = new PinPanel[_NumberInputPins];
        for (int i = 0; i < inputPins.Length; i++)
        {
            inputPins[i] = new PinPanel();
            inputPins[i].Click += OnClickPinPanel;
            this.Controls.Add(inputPins[i]);
        }
        if (outputPins != null)
        {
            for (int i = 0; i < outputPins.Length; i++)
            {
                if (outputPins[i] != null && !outputPins[i].IsDisposed)
                {
                    outputPins[i].Dispose();
                }
            }
        }
        outputPins = new PinPanel[_NumberOutputPins];
        for (int i = 0; i < outputPins.Length; i++)
        {
            outputPins[i] = new PinPanel();
            outputPins[i].Click += OnClickPinPanel;
            this.Controls.Add(outputPins[i]);
        }
    }

    private void OnClickPinPanel(object sender, EventArgs e)
    {
        PinPanel p = (PinPanel)sender;
        if (inputPins.Contains(p))
        {
            ClickedPinPanel?.Invoke(Array.IndexOf(inputPins, p), true);
        }
        else if (outputPins.Contains(p))
        {
            ClickedPinPanel?.Invoke(Array.IndexOf(inputPins, p), false);
        }
    }

    private void RepositionPins()
    {
        int PinRowHeight, PinHeight;
        if (inputPins != null)
        {
            PinRowHeight = (int)((double)this.Height / (double)_NumberInputPins);
            PinHeight = (int)Math.Min((double)(PinRowHeight / 2), (double)this.Height * 0.05);
            for (int i = 0; i < inputPins.Length; i++)
            {
                if (inputPins[i] != null && !inputPins[i].IsDisposed)
                {
                    inputPins[i].SetBounds(0, (int)((i * PinRowHeight) + (PinRowHeight /2 ) - (PinHeight / 2)), PinHeight, PinHeight);
                }
            }
        }
        if (outputPins != null)
        {
            PinRowHeight = (int)((double)this.Height / (double)_NumberOutputPins);
            PinHeight = (int)Math.Min((double)(PinRowHeight / 2), (double)this.Height * 0.05);
            for (int i = 0; i < outputPins.Length; i++)
            {
                if (outputPins[i] != null && !outputPins[i].IsDisposed)
                {
                    outputPins[i].SetBounds(this.Width - PinHeight, (int)((i * PinRowHeight) + (PinRowHeight / 2) - (PinHeight / 2)), PinHeight, PinHeight);
                }
            }
        }
    }

}

在初始化int main() { string s; s='a'; cout<<s.size(); cout<<s<<" "; cout<<s[0]; return 0; } 之后,只需起飞[0],因为ss类型,而不是string类型。

只需写char,它就可以工作。