2013-11-19 3 views
0

Это часть более крупной программы, которую я пишу, которая по какой-то причине дает мне бесконечный цикл. Он ведет себя так, как ожидалось, для таких ресурсов, как «Roundup» и «What is up». Они говорят пользователю, что выбранное слово должно быть правильной длины и содержать только строчные буквы. Однако такие входы, как «округление» и «округление», вызывают бесконечное повторение сообщения, в котором пользователю предлагается выбрать слова правильной длины и формата. Может кто-то, пожалуйста, помогите мне выяснить, в чем проблема? Я бы очень признателен. Благодаря!Я не могу понять, почему я получаю этот бесконечный цикл

#include <iostream> 
#include <fstream> 
#include <cstring> 
#include <cstdlib> 
#include <cctype> 
#include <ctime> 
#include <algorithm> 
#include <iomanip> 
#include <string> 

using namespace std; 

const int MINWORDLENGTH = 4; 
const int MAXWORDLENGTH = 6; 
const int NUMWORDS = 9000; 


const char WORDFILENAME[] = "C:/Users/Paul/Desktop/words.txt"; 

int randInt(int lowest, int highest) 
{ 

    if (highest < lowest) 
     swap(highest, lowest); 
    return lowest + (std::rand() % (highest - lowest + 1)); 
} 

int loadWords(char words[][MAXWORDLENGTH+1], int maxWords) 
{ 
    ifstream wordfile(WORDFILENAME); 
    if (! wordfile) 
    { 
     cout << "Cannot open " << WORDFILENAME << endl; 
     return -1; 
    } 
    const int LINELIMIT = 10000; 
    char line[LINELIMIT]; 
    int numWords = 0; 
    while (wordfile.getline(line, LINELIMIT)) 
    { 
     if (numWords == maxWords) 
     { 
      cout << "Using only the first " << numWords 
       << " words from " << WORDFILENAME << endl; 
      break; 
     } 
     int k; 
     for (k = 0; islower(line[k]); k++) 



     if (line[k] == '\r') 
       line[k] = '\0'; 

     if (line[k] == '\0' && k >= MINWORDLENGTH && k <= MAXWORDLENGTH) 
     { 
      strcpy(words[numWords], line); 
      numWords++; 
     } 
    } 
    return numWords; 
} 
bool found(char characters[], int length, char target) //seaches for the target character and returns true if it is found. Otherwise returns false. 
{ 
     for (int i= 0; i<length; i++) 
      if (characters[i] == target) 
       return true; 


    return false; 



bool wordFound(const char allWords[][7], char targetWord[], int numWords) //searches the array of loaded words for the target word. Returns true if it is found, otherwise returns false. 
{ 
for(int j=0; j<numWords; j++) 
    if (!strcmp(targetWord,allWords[j])) 
     return true; 

return false; 
} 
bool properFormat(char guess[],int size) //checks that words are of the proper length and contain only lowercase letters 
{ 
if ((guess[0] == '\0')||strlen(guess) > MAXWORDLENGTH || strlen(guess) < MINWORDLENGTH) 
    return false; 
for (int i = 0; i < strlen(guess) ; i++) 
    if (!islower(guess[i])) //return false if a nonlowercase letter, punctuation or a space is found 
     return false; 

return true; 
} 

int manageOneRound(char words[][7],int num, int numwords) 
{ 
    int x=num; 
    int y=numwords; 

    cout<<"The hidden word is "<<strlen(words[y])<<" letters long"<<endl; 
    cerr<<words[y]<<endl; 
    int tries =0; 
    char guess[7]; 

    int appearances[MAXWORDLENGTH]; 
    char characters[MAXWORDLENGTH]=""; 

    int k=0; 
    for (int j = 0; j < strlen(words[y]); j++) 
     if (!found(characters,strlen(words[y]),words[y][j])) //put characters that make up word into an array. Each character appears only once. 
     { 
      characters[k] = words[y][j]; 
      k++; 
     } 

      while (strcmp(guess,words[y])) //while the guessed word is not the correct word 
    { 

     cout<<"Trial word: "; 

     cin.getline(guess, MAXWORDLENGTH+1,'\n'); 
     if (!properFormat(guess,strlen(guess))) 
      cout<<"Your trial word must be a word of "<<MINWORDLENGTH<<" to "<<MAXWORDLENGTH<<" lower case letters"<<endl; 
     else if (!wordFound(words,guess,x) && guess[0] != '\0') //determine if trial word is known 
      cout<<"I don't know that word"<<endl; 
     else 
     { 

     int guessAppearances[MAXWORDLENGTH]; 
     char guessCharacters[MAXWORDLENGTH]=""; 

     int l=0; 
     for (int j = 0; j < strlen(guess); j++) 
     { 
      if (!found(guessCharacters,strlen(guess),guess[j])) //Store characters that make up trial word in an array 
      { 
       guessCharacters[l] = guess[j]; 
       l++; 
      } 
     } 

     alphabetize(characters,k); 
     alphabetize(guessCharacters,l); //alphabetize the word characters and the guess word characters 



     for (int j = 0; j < k; j++) 
      appearances[j]=countAppearances(words[y], strlen(words[y]), characters[j]); 
     for (int j = 0; j < l; j++) 
      guessAppearances[j]=countAppearances(guess, strlen(guess), guessCharacters[j]); 
     //count the number of appearnces of the characters in the word and the guess word. 


     int comp[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 
     int n=0; 

    for (int i=0 ;i<k;i++) 
     for(int j=0; j<l; j++) 
     { 
      if (characters[i]==guessCharacters[j] && appearances[i]==guessAppearances[j]) //if the characters match, and the number of its appearances matches, the current position of comp is set to the number of appearances 
      { 
       comp[n]=appearances[i]; 
       n++; 
      } 
      else if (characters[i]==guessCharacters[j] && appearances[i] > guessAppearances[j])//if the characters match, and the number of appearances of the letter is less than the correct number, the current position of comp is set to the number of its appearances in the guess word. 
      { 
       comp[n]=guessAppearances[j]; 
       n++; 
      } 
      else if (characters[i]==guessCharacters[j] && appearances[i] < guessAppearances[j])//if the characters match, and the number of appearances of the letter is greater than the correct number, the current position of comp is set to the number of its appearances in the correct word. 
      { 
       comp[n]=appearances[i]; 
       n++; 
      } 
     } 

     int correctSum=0; 
     for (int w=0; w <n; w++) //the number of correct letters is the sum of the elements in comp 
      correctSum+= comp[w]; 
     if (strcmp(guess,words[y])) 
      cout<<correctSum<<endl; 
     } 
     tries++; 

} 
      return tries; 
} 
int main() 
{ 
int numRounds; 

int max=0; 
int min=10000; 

cout<<"How many rounds do you want to play? "; 
cin>>numRounds; 
cin.ignore(10000, '\n'); 
if (numRounds < 1) 
{ 
    cout<<"The number of rounds must be positive"<<endl; 
    return 0; 
} 
char words[NUMWORDS][MAXWORDLENGTH + 1]; 

int x = loadWords(words, 10000); 

srand(time(0)); 
int sum = 0; 
for (int round=1; round <= numRounds; round++) 
{ 

    cout<<"Round "<<round<<endl; 
    int y= randInt(0, x); 


    int tries = manageOneRound(words,x,y); 


sum+=tries; 
    //cerr<<sum<<endl; 
cout<<"You got it in "<<tries<<" tries"<<endl; 
if (tries < min) 
    min = tries; 
if (tries > max) 
    max = tries; 
double average= sum/round; 
cout<<"Average: "<<setprecision(2)<<fixed<<average<<setprecision(1)<<fixed<<", minimum: "<<min<<", maximum: "<<max<<endl<<endl; 

} 
return 0; 
} 
+0

Что произойдет, если вы выполните код в отладчике? –

+0

Я не вижу, как приведенный здесь код может привести к повторной печати инструкций. Часть 'cout' кода не находится внутри каких-либо циклов. Вы уверены, что цитируете правильные части своей программы? – karadoc

+2

Просьба предоставить полный образец кода, который воспроизводит поведение, которое вы видите. Код, включенный в вопрос, не будет компилироваться и не приведет к бесконечному циклу. –

ответ

1

Проблема с вами кода является то, что ваш буфер имеет MAXWORDLENGTH = 6 + 1 = 7, поэтому при вводе облавы длина «облавы» является 8, так содержимое вашей буфера будет догадка = {r, o, u, n, d, u, \ 0}, а когда длина ввода больше 6, это приводит к следующему оператору getline, получающему '\ n', который не был взят в этом буфере, и это выполняется непрерывно ведущий бесконечный цикл while. Если длина ввода меньше 6, например, «раунд», это будет работать нормально. Вы пытаетесь читать в буфер больше, чем его емкость и тем самым приводить к повреждению памяти и неопределенному поведению.

 Смежные вопросы

  • Нет связанных вопросов^_^