程序在C ++中只打印数组中的前三个字符

时间:2018-01-14 18:33:18

标签: c++ c++11

我的程序是将字符读入数组并将其显示到控制台。但我不知道为什么它只读前3个字符。

#include <iostream>

using namespace std;
int main() {    
    int length=0,i;
    char str[10];
    cout<<"Enter a string"<<"\n";

    for(i=0; str[i] != '\0'; i++) {
        cin>>str[i];
    }

    for(int i=0; str[i]!='\0'; i++) {
        cout<<str[i];
        length++;
    }
    cout<<"\n"<<"Length of the string="<<""<<length<<"\n";
}

输出如下:

enter image description here

5 个答案:

答案 0 :(得分:4)

以下是我注意到的一些问题:

  1. 在初始化之前,您正在检查str的内容。
  2. 您假设从流中提取的字符串将以空值终止,但事实并非如此。
  3. 您没有检查cin是否正常工作
  4. 您不检查以确保字符串不超过10个字符,这可能会导致您溢出缓冲区的末尾
  5. 当您检查数组的长度时,再次假设该字符串为空终止
  6. 如果您想解决这些问题并仍然使用char缓冲区,请参阅user4581301的综合答案。但是,我建议只需切换到std::string.例如:

    #include<iostream>
    
    using namespace std;
    
    int main()
    {
        string str;
        cout<<"Enter a string"<<"\n";
        if (cin >> str) {
            cout << str << endl;
            cout << "Length of the string = " << str.length() << endl;
        }
    }
    

答案 1 :(得分:3)

TL; DR版本

std::string str; //use std::string. practically no reasons not to in C++
if (cin >> str) // read into string and test that read succeeded.
{
    std::cout << str << '\n'
              << "Length of the string=" << str.length() << endl;
}

解释和挽救Asker的版本

for(i=0; str[i] != '\0'; i++){ // str[i] tested here
    cin>>str[i]; // but it has no assigned value until here.

在为其分配值之前使用str[i]。该程序可能在为str分配的内存块中找到了一个空字符并提前停止,但从技术上讲,如果使用未初始化的变量,任何事情都可能发生。例如,在找到null之前,您获得了预期结果3次。该程序永远不会找到null并永远运行。它可能会下雨独角兽。任何东西。

int i = 0;
do {
    cin>>str[i];
} while (str[i++] != '\0');

然后读取测试。但是流中的数据行不是C样式的字符串,并且不以null结尾。

int i = 0;
do {
    cin>>str[i];
} while (!std::isspace(str[i++]));

在找到空格时退出,通常表示单词的结尾,而不是null。

但如果cin>>str[i];由于某种原因失败怎么办?

int i = 0;
do {
    cin>>str[i];
} while (cin && !std::isspace(str[i++]));

添加测试以确保读取内容。但是,如果超过10个字符且char str[10];溢出会怎么样?

int i = 0;
do {
    cin>>str[i];
} while (cin && !std::isspace(str[i]) && ++i < sizeof(str));

除非我正在阅读这是合法的,除非我读 [expr.cond] [expr.log.and] 错误,排序时间{ ++i中出现的{1}}保证不会影响!std::isspace(str[i]) && ++i < sizeof(str))

但是如果你在找到null之前用完了空间怎么办? !std::isspace(str[i])未终结,不是字符串!这会在程序的后期破坏for循环。

str

我认为这涵盖了您可能遇到的所有内容。

答案 2 :(得分:2)

您逐字逐字地阅读并将其存储在str[i];但是在检查i++之前你会增加str[i]!='\0'

此方法存在两个问题:首先,检查在该时间点尚未写入的位置的值。其次,cin>>str[i]永远不会写字符串终止字符 - 它只读取有效字符,如果输入终止(例如通过EOF),则不会写入任何内容。

所以你正以错误的方式接近这个。

如果您想要读取最多10个字符直到新行(即当用户按下回车键时),请使用fgets。或者 - 这是首选选项 - 使用cin并写入std::string - 对象。

int main()
{
    std::string str;
    cin >> str;
    std::cout << str << std::endl;
}

答案 3 :(得分:1)

str [i]!='\ 0'检查存储在str [i]中的预先存在的数据,而不是用户输入值。

答案 4 :(得分:0)

添加字符串初始化:

char str[10] = {'\0'};

并用以下内容更改阅读:

char c;
for(int i = 0; cin>> c && c!=/*add your termination cond. here*/ && i < 10;++i)
    str[i] = c;

因此,您可以确保字符串填充正确的值并适当终止。

但更好的解决方案是使用 std :: string 。在这种情况下,您不必检查大小,因为字符串会自行增长。例如:

    std::string str;
    for(char c; cin>>c && c!=/*add your termination cond. here*/;) 
        str += c;