【问题标题】:First iteration failing第一次迭代失败
【发布时间】:2013-08-28 04:55:20
【问题描述】:

我对 C++ 还很陌生,但从逻辑上讲,我认为这应该可行。

我有一个函数,它接受用户的输入来设置数组的内存分配:

void setarraynum(){
  string mystr;
  cout<<"Please enter the size of your array: ";
  getline(cin, mystr);
  stringstream(mystr)>>arraynum;
  array = new int [arraynum];
  cout<<"\n";
}

arraynum 和 array 是全局变量:

int arraynum;
int * array;

然后我有一个接受数组输入的函数:

void setarray(){
  string mystr;
  cout<<"Please enter "<<arraynum<<" numbers:\n";
  for(int n=0; n<arraynum; n++){
    getline(cin, mystr);
    stringstream(mystr)>>array[n];
  };
cout<<"\n";
}

在输入数组编号时会出现问题,数组的第一个实例 (array[0]) 会自动设置为 0。就好像循环在不询问用户输入的情况下迭代第一次迭代一样。然后它会照常询问用户。

有什么想法吗?

谢谢。

*编辑(根据要求,全部代码):

#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int arraynum;
int * array;
bool isin = false;
int input;
char order;

void insertionsortdesc(int a[]);
void insertionsortasc(int a[]);
void getarray(int a[]);
void isinarray(int a[], int b);

void setsearch();
void setarray();
void setarraynum();
void setorder();

int main(){

 cout<<"\n//// INPUT ////\n\n";

 setarraynum();
 setorder();
 setarray();
 setsearch();

 if(order=='a'){insertionsortasc(array);
 }else if(order=='d'){insertionsortdesc(array);};

 cout<<"//// OUTPUT ////\n\n";
 getarray(array);
 isinarray(array, input);

 return 0;
}

void setorder(){
 bool isvalid = false;

 while(!isvalid){
  cout<<"Ascending or Descending [a/d]: ";
  cin>>order;
  if(order=='a'||order=='d'){isvalid = true;
  }else{cout<<"Please enter a valid option!\n";};
 };

cout<<"\n";
}

void setarraynum(){
 string mystr;
 cout<<"Please enter the size of your array: ";
 getline(cin, mystr);
 stringstream(mystr)>>arraynum;
 array = new int [arraynum];
 cout<<"\n";
}

void setsearch(){
 string mystr;
 cout<<"Search for (int): ";
 getline(cin, mystr);
 stringstream(mystr)>>input;
 cout<<"\n";
}

void setarray(){
 string mystr;
 cout<<"Please enter "<<arraynum<<" numbers:\n";
 for(int n=0; n<arraynum; n++){
  getline(cin, mystr);
  stringstream(mystr)>>array[n];
 };
cout<<"\n";
}

void insertionsortdesc(int a[]){
 for(int n=1; n<arraynum; n++){
  int key = a[n];
  int j = n-1;
  while((j>=0)&&(a[j]<key)){
   a[j+1] = a[j];
   j -= 1;
  };
  a[j+1]=key;
 }
}

void insertionsortasc(int a[]){
 for(int n=1; n<arraynum; n++){
  int key = a[n];
  int j = n-1;
  while((j>=0)&&(a[j]>key)){
   a[j+1] = a[j];
   j -= 1;
  };
  a[j+1]=key;
 }
}

void isinarray(int a[], int b){
 for(int n=0; n<arraynum; n++){
  if(a[n] == b){
   isin = true;
   break;
  };
 };

 if(isin){
  cout<<b<<" is present in the given array.";
 }else{
  cout<<b<<" is not present in the given array.";
 };

 cout<<"\n\n";
}

void getarray(int a[]){
 cout<<"Sorted array sequence: ";
 for(int n=0; n<arraynum; n++){
  cout<<a[n]<<", ";
 };
 cout<<"\n\n";
}

【问题讨论】:

  • setarray中,打印出getline读到的每一行,验证输入是否正确。另外,std::vector 有什么问题?
  • 使用std::vector而不是new[],并使用参数和返回值而不是使用全局变量。
  • 当我这样做时,第一次迭代不打印。假设我说数组内存分配为 5,setarray 循环只要求 4 个输入。我还不知道 std::vector 是什么。我目前正在学习并使用我学到的东西来制作一个简单的排序程序。
  • 您可以直接cin &gt;&gt; arraynum; 而不是stringstream(mystr) &gt;&gt; arraynum;。除非您只是想学习如何使用stringstream,否则据我所知没有理由使用这种间接方式。 :)
  • 您可能还想在调试器中逐行执行代码,看看实际发生了什么。

标签: c++ arrays loops


【解决方案1】:

我强烈建议您直接使用cin &gt;&gt; arraynum;,而不是在stringstream(mystr) &gt;&gt; arraynum; 范式中读取整数。

来自 C++ 参考 http://www.cplusplus.com/reference/string/string/getline/ for getline

如果找到分隔符,则将其提取并丢弃,即它是 没有存储,下一个输入操作将在它之后开始。

所以这就是问题所在。 正如@Vaughn 所指出的,您在setorder 函数中使用cin &gt;&gt; order;,这会将拖尾\n 留在输入缓冲区中。

您的代码学到的教训是,在处理 I/O 问题时,请确保以相同的范例调用函数。

【讨论】:

    【解决方案2】:

    问题就在这里:

    cout<<"Ascending or Descending [a/d]: ";
    cin>>order;
    

    您正在阅读“a”或“d”,但不是回车。

    当你到达这里时:

    cout<<"Please enter "<<arraynum<<" numbers:\n";
    for(int n=0; n<arraynum; n++){
      getline(cin, mystr);
    

    getline 会将您在 'a' 或 'd' 之后和回车之前输入的任何内容视为它所获得的行 - 可能是空白。

    解决它的一种方法是在阅读 order 后添加另一个 getline

    cout<<"Ascending or Descending [a/d]: ";
    cin>>order;
    string rest_of_line;
    getline(cin,rest_of_line);
    

    【讨论】:

      【解决方案3】:

      我稍微修改了您的代码,它的行为符合预期。我建议您向用户表明他是否应该对他的输入进行定界,或者他应该如何定界。我宁愿使用向量而不是数组。您已经没有取消分配您的数组 - 这并不重要,但它可能在另一个程序中。

      另外,我不知道你为什么在 cin 已经允许你获取整数时使用 getline(见代码):

      #include <iostream>
      #include <sstream>
      #include <string>
      
      int arraynum;
      int * array;
      bool isin = false;
      int input;
      char order;
      
      void insertionsortdesc(int a[]);
      void insertionsortasc(int a[]);
      void getarray(int a[]);
      void isinarray(int a[], int b);
      
      void setsearch();
      void setarray();
      void setarraynum();
      void setorder();
      
      int main(){
      
       std::cout<<"\n//// INPUT ////\n\n";
      
       setarraynum();
       setorder();
       setarray();
       setsearch();
      
       if(order=='a'){insertionsortasc(array);
       }else if(order=='d'){insertionsortdesc(array);};
      
       std::cout<<"//// OUTPUT ////\n\n";
       getarray(array);
       isinarray(array, input);
      
       return 0;
      }
      
      void setorder(){
       bool isvalid = false;
      
       while(!isvalid){
        std::cout<<"Ascending or Descending [a/d]: ";
        std::cin>>order;
        if(order=='a'||order=='d'){isvalid = true;
        }else{std::cout<<"Please enter a valid option!\n";};
       };
      
      std::cout<<"\n";
      }
      
      void setarraynum(){
       std::cout<<"Please enter the size of your array: ";
       while( !( std::cin >> arraynum ) )
       {
         std::cout << "Please enter integer!";
       }
       array = new int [arraynum];
       std::cout<<"\n";
      }
      
      void setsearch(){
       std::cout<<"Search for (int): ";
       while( !(std::cin >> input) )
       {
         std::cout << "Please enter integer!" << std::endl;
       }
       std::cout<<"\n";
      }
      
      void setarray(){
       std::ostringstream msgStream;
       msgStream << "Please enter "<<arraynum<<" numbers:";
       std::cout << msgStream.str() << std::endl;
      
       for(int n=0; n<arraynum; n++){
         if( !(std::cin >> array[n]) ){
           n = 0;
           std::cout << msgStream.str() << std::endl;
         }
       }
      std::cout<<"\n";
      }
      
      void insertionsortdesc(int a[]){
       for(int n=1; n<arraynum; n++){
        int key = a[n];
        int j = n-1;
        while((j>=0)&&(a[j]<key)){
         a[j+1] = a[j];
         j -= 1;
        };
        a[j+1]=key;
       }
      }
      
      void insertionsortasc(int a[]){
       for(int n=1; n<arraynum; n++){
        int key = a[n];
        int j = n-1;
        while((j>=0)&&(a[j]>key)){
         a[j+1] = a[j];
         j -= 1;
        };
        a[j+1]=key;
       }
      }
      
      void isinarray(int a[], int b){
       for(int n=0; n<arraynum; n++){
        if(a[n] == b){
         isin = true;
         break;
        };
       };
      
       if(isin){
        std::cout<<b<<" is present in the given array.";
       }else{
        std::cout<<b<<" is not present in the given array.";
       };
      
       std::cout<<"\n\n";
      }
      
      void getarray(int a[]){
       std::cout<<"Sorted array sequence: ";
       for(int n=0; n<arraynum; n++){
        std::cout<<a[n]<<", ";
       };
       std::cout<<"\n\n";
      }
      

      【讨论】:

      • 谢谢你。我并不期望有完美的代码,因为我最近才开始学习 c++,而且我仍在掌握这些概念。我什至还没有开始学习课程。这个程序是为了简单地“测试”我在过去几天学到的东西(以及学习插入排序算法)。我什至不确定自己的定义是什么意思:P。此外,我已经了解了向量,但我仍在学习以前从未见过 :: 运算符的基础知识。 (其他语言除外)。再次感谢。
      • 没有汗水。目前您正在使用空格作为分隔符。因此,用户必须输入由空格分隔的整数。这没关系,但只是向用户表明这一点。会发生什么,例如:如果用户输入 1;2;3 或 1,2,3... 当我第一次运行代码时,它从使用的角度让我感到困惑。对我来说最重要的一点是来自@Summer_More... 的那一点。
      • 啊,我明白了。所以只需添加诸如“由 分隔?”之类的内容。
      猜你喜欢
      • 2023-04-02
      • 1970-01-01
      • 2021-12-14
      • 1970-01-01
      • 2016-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-16
      相关资源
      最近更新 更多