2017-06-29 18 views
0

我想在C++(11)中做一个简单的猜字游戏,因为它需要一个"hidden word"显示给玩家我已经做了两个字符串;第一个可见的"test",另一个只填充下划线"____"。我用string::iterator做了一个循环,将字符串中的每个字符与用户输入的给定(char)输入进行比较。C++ <algorithm>替换所有发生的不工作

这里的问题是,它并没有在字符串中代替人OCCURENCES的第一次我给这将导致“t__t”的“t”的输入,而不是“t___

为过程我使用的从<algorithm>头 看起来像这样的replace功能:

replace(str.begin(), str.end(), str.at(char_idx), newLetter); 


和这个函数是福尔循环内它迭代槽字符串;在另一个叫功能可按checkLetter()

void checkLetter(char &newLetter, string &randstr, int &strlen, string &hiddenWord){ 
    string::iterator it; 
    char char_idx; 
    for(auto it = randstr.begin(); it != randstr.end();++it){ 
     if(*it == newLetter){ 
      char_idx=randstr.find(*it); 
      replace(hiddenWord.begin(), hiddenWord.end(), hiddenWord.at(char_idx), newLetter); 
     } 
    } 
    cout << hiddenWord << endl; 
} 

现在这是输出的样子:

The Word is 4 letters long. 

t 
t___ 
e 
te__ 
s 
tes_ 
t 
tes_ 

,但是当我跑的是如

string RandomWord = "test"; 
replace(RandomWord.begin(),RandomWord.end(),'t','S'); 
cout << RandomWord << endl; 

一个简单的版本,它提供了'SesS'

全部代码:

#include <iostream> 
#include <fstream> 
#include <string> 
#include <vector> 
#include <algorithm> 
using namespace std; 

// Function Declaration 
string getRandWord(); 
void checkLetter(char&, string&, int&, string&); 

int main() { 
// string RandomWord = getRandWord(); 
    string RandomWord = "test"; 
    string hiddenWord = ""; 

    unsigned long int _length_ = RandomWord.length(); 
    int chances = int(_length_)+1; 
    char newLetter; 

    hiddenWord.append((_length_),'_'); 
    cout << "The Word is "<< _length_ <<" letters long." << endl; 
    while(chances > 0){ 
     cin >> newLetter; 
     checkLetter(newLetter, RandomWord, chances, hiddenWord); 

     chances--; 
    } 

    return 0; 
} 


// Functions 

void checkLetter(char &newLetter, string &randstr, int &strlen, string &hiddenWord){ 
    string::iterator it; 
    char char_idx; 
    for(auto it = randstr.begin(); it != randstr.end();++it){ 
     if(*it == newLetter){ 
      char_idx=randstr.find(*it); 
      replace(hiddenWord.begin(), hiddenWord.end(), hiddenWord.at(char_idx), newLetter); 
     } 
    } 
    cout << hiddenWord << endl; 
} 

string getRandWord(){ 
    string filePath = "/Users/nedimkanat/XCODE/testcpp/testcpp/"; 
    enum sizes { 
     ARRAY_SIZE = 5 
    }; 
    // set seed 
    srand((unsigned)time(0)); 

    // get random int between 0 and 5 
    int randint = rand() % ARRAY_SIZE; 

    // str to store each line from file 
    string str; 

    // array to store 5 (random) words 
    vector<string> arr; 

    // initialize file object & open file 
    ifstream file(filePath+"words.txt"); 
    int counter = 0; 

    // loop trough file 
    if (file.is_open()){ 
     while (getline(file,str) && counter < ARRAY_SIZE){ 
      arr.push_back(str); 
      counter++; 
     } 
     file.close(); 
    } else { 
     cout << "File is not open" << endl; 
    } 

    // send away random word 
    if(arr.empty()){ 
     cout << "CANCER" << endl; 
    } 
    return arr.at(randint); 
} 

回答

1

如果根据你的代码,你不应该使用std :: replace,因为第三个参数(意思是替换字母)可以在文本中出现两次。所以你可以像下面这样替换字母。

void checkLetter(char &newLetter, string &randstr, int &strlen, string &hiddenWord){ 
    string::iterator it; 
    for(auto it = randstr.begin(); it != randstr.end();++it){ 
     if(*it == newLetter){ 
      hiddenWord.at(it - randstr.begin()) = newLetter; 
     } 
    } 
    cout << hiddenWord << endl; 
} 
+0

非常感谢大家:) –

2

如果我理解你正确,你基本上想要transform一个字符串到另一个?

使用std::transform的双输入迭代器过载应该是您需要的函数。第一个输入容器可以是要替换的下划线的字符串,而第二个输入容器是包含实际单词的字符串。然后你提供一个函数或lambda使用输入字母作为状态或捕获,并有函数返回来自第一个容器(掩码字)的当前字母,除非字母匹配第二个容器中的当前字母(单词被猜到)。输出迭代器是掩码字(与第一个输入迭代器相同)。

也许是这样的例子程序显示:

#include <iostream> 
#include <string> 
#include <algorithm> 

int main() 
{ 
    std::string word = "foobar"; // The word to guess 
    std::string masked = "______"; // The masked word, that will be unmasked letter by letter 

    // "Guess" some letters...   
    for (auto const letter : { 'f', 'a', 'x', 'o', 'y', 'r', 'b' }) 
    { 
     std::cout << "Before '" << letter << "': \"" << masked << "\"\n"; 

     // Convert the masked word into a less masked word 
     // But only if the letter is found in the word to guess 
     std::transform(std::begin(masked), std::end(masked), std::begin(word), 
         std::begin(masked), 
         [letter](char const& masked_letter, char const& word_letter) 
         { 
          if (letter == word_letter) 
           return word_letter; 
          else 
           return masked_letter; 
         }); 

     std::cout << "After '" << letter << "': \"" << masked << "\"\n"; 
    } 
} 

Example of it running here

+0

range-for循环中'auto'的类型是什么? – cppxor2arr

+0

@ 6EQUJ5这应该是一个'char'。 –

+0

哦等等问错了。我的意思是range-for循环中的'{...}'的类型。好吧,我现在知道了。 'std :: initializer_list' – cppxor2arr