【问题标题】:Loop crashing program having to do with 2D arrays与二维数组有关的循环崩溃程序
【发布时间】:2011-01-15 23:39:01
【问题描述】:

我正在创建一个编码程序,当我指示程序根据字母表创建一个 5X5 网格时,会跳过与某些预定义变量匹配的字母(在运行时由用户输入给定值)。我有一个循环,指示循环继续运行,直到访问数组的值超出范围,循环似乎导致了问题。此代码是标准化的,因此在另一个编译器中编译它应该不会有太大问题。将我的程序分成函数会更好吗?这是代码:

#include<iostream>
#include<fstream>
#include<cstdlib>
#include<string>
#include<limits>

using namespace std;
int main(){


 while (!cin.fail()) {      

char type[81];
char filename[20];
char key [5];
char f[2] = "q";
char g[2] = "q";
char h[2] = "q";
char i[2] = "q";
char j[2] = "q";
char k[2] = "q";
char l[2] = "q";
int a = 1;
int b = 1;
int c = 1;
int d = 1;
int e = 1;
string cipherarraytemplate[5][5]= {
{"a","b","c","d","e"},
{"f","g","h","i","j"},
{"k","l","m","n","o"},
{"p","r","s","t","u"},
{"v","w","x","y","z"}

};
string cipherarray[5][5]= {
{"a","b","c","d","e"},
{"f","g","h","i","j"},
{"k","l","m","n","o"},
{"p","r","s","t","u"},
{"v","w","x","y","z"}

};





cout<<"Enter the name of a file you want to create.\n";

cin>>filename;


ofstream outFile;
outFile.open(filename);
outFile<<fixed;
outFile.precision(2);
outFile.setf(ios_base::showpoint);
cin.ignore(std::numeric_limits<int>::max(),'\n');






cout<<"enter your codeword(codeword can have no repeating letters)\n"; 

cin>>key;

while (key[a] != '\0' ){

while(b < 6){
cipherarray[b][c] = key[a];

 if (  f == "q" ) {
 cipherarray[b][c] = f;
}

 if ( f != "q" && g == "q"  )
 {
cipherarray[b][c] = g;
}

 if ( g != "q" && h == "q" )
 {
cipherarray[b][c] = h;
}

 if ( h != "q" && i == "q"  )
 {
cipherarray[b][c] = i;
}


 if ( i != "q" && j == "q" ) 
{
cipherarray[b][c] = j;
}

 if ( j != "q" && k == "q" )
 {
cipherarray[b][c] = k;
}

 if ( k != "q" && l == "q" )
 {
cipherarray[b][c] = l;
}
a++;
b++;

}

c++;
b = 1;

}

while (c

if (cipherarraytemplate[d][e] == f || cipherarraytemplate[d][e] == g || cipherarraytemplate[d][e] == h || cipherarraytemplate[d][e] == i ||
cipherarraytemplate[d][e] == j || cipherarraytemplate[d][e] == k || cipherarraytemplate[d][e] == l){
 d++;                 
}
else {
cipherarray[b][c] = cipherarraytemplate[d][e];
d++;
b++;
}
if (d == 6){
d = 1;
e++;
}
if (b == 6){
c++;
b = 1;
}

}

 cout<<"now enter some text."<<endl<<"To end this program press Crtl-Z\n";

while(!cin.fail()){

 cin.getline(type,81);

outFile<<type<<endl;
}

outFile.close();
}
} 

我知道会有一些 40 多岁的人偶然发现这篇文章,他已经编程了 20 多年,他会看着我的代码说:“什么是这家伙在做”。

【问题讨论】:

  • 对不起,我还没到 20 多岁,但不得不说同样的话。您的代码中的某些结构将有助于阅读它;)
  • 您不必到四十多岁就想知道自己在做什么... :) 但没关系,每个人都是从初学者开始的。是的,您应该尝试将代码分解为函数,这样可以更轻松地确保各个函数正常工作并使代码更具可读性。此外,数组的索引以 0 而不是 1 开头,这可能是您遇到的问题的一部分。

标签: c++ arrays loops crash


【解决方案1】:

cipherarray 的长度为 [5] 个条目,这意味着它可以使用 (0, 1, 2, 3, 4) 中的任何一个来索引 - 传入 5 超出范围。

将您的 while (b &lt; 6) 修改为 while (b &lt; 5) 以保持在数组范围内(在您检查索引的其他地方也类似)。

【讨论】:

  • 为了可读性,我推荐使用b &lt;= 4。不过,这只是风格。
  • @Maxpm:我更喜欢 (b
【解决方案2】:

具有字母表前五个字母(大小为 5)的数组可以这样可视化:

Index 0: a
Index 1: b
Index 2: c
Index 3: d
Index 4: e

如您所见,第一个值的索引实际上为零。这可能会让人感到困惑!

char MyCharacterArray[5]; // Initializes a one-dimensional character array with a size of five.
MyCharacterArray[0] = 'a'; // Sets the first value to a.
MyCharacterArray[4] = 'e'; // Sets the last value to b.
MyCharacterArray[5] = `f`; // This will generate errors, as the last index of MyCharacterArray is 4!

遍历数组的基本循环可能如下所示:

for (int Index = 0; Index <= 4; Index++)
{
    // ...
}

这是您的代码遇到问题的地方。你的 while 循环使用了这个等价物:

while (Index < 6)

与此相同:

while (Index <= 5)

所以在循环的最后一次运行中,Index 是 5,它会尝试访问数组范围之外的值。

【讨论】:

    【解决方案3】:

    此外,对于非动态分配数组,您可以使用 sizeof() 来了解数组大小:

    const char tab[] = "hello world";
    
    for (unsigned int i = 0; i < sizeof(tab); ++i) { //then you can easily iterate on each, including \0
          std::cout << tab[i] << std::endl; 
    }
    

    这仅适用于本地数组,sizeof(char*) 将返回指针的大小(4/8 字节)

    【讨论】:

      猜你喜欢
      • 2015-01-28
      • 2015-08-22
      • 2015-06-05
      • 1970-01-01
      • 2014-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多