【问题标题】:C++ - Replacing "_" with a characterC++ - 用字符替换“_”
【发布时间】:2014-03-07 10:28:45
【问题描述】:

使用 C++,我正在尝试制作一个刽子手游戏,以便更好地使用 C++ 和一般编程。无论如何,我面临的问题是我不确定如何用用户猜到的字母替换字符串中的破折号。

我认为我的问题在于选择的单词是从数组中随机选择的,我不确定如何在包含猜测字符的随机选择的字符串中查找位置。

我已注释掉导致问题的区域。

#include <iostream>
#include <array>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <cstddef>
#include <algorithm>

using namespace std;

int main()
{
    string words[3] = {"stack", "visual", "windows"};
    string guess;

    cout << "Welcome to hangman.\n";
    cout << "\n";

    srand(time(NULL));

    int RandIndex = rand() % 3;
    string selected = words[RandIndex];

    for (int i = 1; i <= selected.size(); i++) {
        cout << "_ ";
    }

    cout << "\n";
    cout << "\nType in a letter: ";
    cin >> guess;
    cout << "\n";

    if (selected.find(guess) != string::npos) {
        /*for (int i = 1; i <= selected.size(); i++) {
            if (selected.find(guess) != string::npos) {
                cout << "_ ";
            } else {
                cout << guess << " ";
            }
        }*/
    } else {
        cout << "\nNay!\n";
        cout << "\n";
    }

    cout << "\n";
    cout << "\n";

    system("PAUSE");
    return 0;
}

我正在考虑使用replace() 函数,但我在这里面临的问题是我没有替换selected 变量中的字符串,而是在对单词本身进行迭代,如果这有任何意义吗?

【问题讨论】:

  • 我在大学的时候不得不做一个刽子手游戏。我将单词存储在一个字符串中,并在字符串中有一个不同字符的向量。显示单词中的每个字符时,检查它是否在向量中,如果是,则显示下划线。当用户猜测正确时,您从向量中删除字符。

标签: c++ arrays replace


【解决方案1】:

使用第二个字符串,它用下划线初始化。如果find 函数返回string::npos,它将返回字符串中的位置,这与您应该在字符串中更改下划线的位置相同。

【讨论】:

    【解决方案2】:

    您实际上需要使用第二个字符串来存储“猜测的”字符串;这是因为您需要跟踪所有猜测的字母并显示它们。

    类似:

        string s ="test";
        string t="";  //empty string
    
        for(int i=0;i<s.size();i++)
            t.append("_");    //initialize the guess string
        cout<<t<<'\n'; 
    
        char c;
        cin >> c;
    
        int pos = s.find(c);   //get the first occurrence of the entered char
        while(pos!=-1)         //look for all occurrences and replaced them in the guess string
        {
          t.replace(pos,1,1,c);   
          pos = s.find(c, pos+1);
    
        }
    

    【讨论】:

    • 在 Visual Studio 上,我相当于行 t.replace(pos,1,1,c); 给了我错误 'std::basic_string&lt;_Elem,_Traits,_Alloc&gt; &amp;std::basic_string&lt;_Elem,_Traits,_Alloc&gt;::replace(unsigned int,unsigned int,const _Elem *,unsigned int)' : cannot convert parameter 3 from 'int' to 'const char *';这是为什么呢?
    • 如果你传递一个字符串而不是一个字符,通常会发生这种情况;所以请确保 c 不包含字符串终止 '\0';或者你可以尝试传递 c[0],它应该是字符串中的第一个字符。
    • 在你的代码中你正在读入一个字符串变量而不是一个字符变量。这可能就是您收到错误的原因 - 我编辑了我的回复以进行澄清
    • 啊,我有 c 作为字符串数据类型。这个解决方案有效,非常感谢。
    【解决方案3】:

    我认为您需要在循环时保持一些额外的状态 - 以跟踪哪些字母已经/没有被猜到。

    您可以添加一个新字符串 current_state,该字符串最初设置为与单词相同的长度,但都是下划线。然后,当玩家猜测一个字母时,您会在原始单词中找到该字母的所有实例,并将下划线替换为猜测的字母,在所有找到的位置,但在 current_state 中。

    【讨论】:

      【解决方案4】:

      首先我会初始化一个新字符串来显示隐藏的单词:

      string  stringToDisplay = string(  selected.length(), '_');
      

      然后对于用户给出的每个字母,我会像这样循环: (假设猜测是字母)

      size_t searchInitPos = 0;
      size_t found = selected.find(guess, searchInitPos));
      if (found == string::npos)  
      {
          cout << "\nNay!\n";
                  cout << "\n";
      }
      while( found != string::npos)
      {
          stringToDisplay[found] = guess;
          searchInitPos = found+1;
          found = selected.find(guess, searchInitPos));
      }
      cout << stringToDisplay;
      

      希望这会有所帮助

      【讨论】:

        【解决方案5】:

        我认为应该是这样的:

        string words[3] = {"stack", "visual", "windows"};
        char guess;
        string display;
        
        cout << "Welcome to hangman.\n";
        cout << "\n";
        
        srand(time(NULL));
        
        int RandIndex = rand() % 3;
        string selected = words[RandIndex];
        
        for (int i = 0; i < selected.size(); i++) {
            display.insert(0, "_ ");
        }
        cout << display;
        
        while(display.find("_ ") != string::npos) {
            cout << "\n";
            cout << "\nType in a letter: ";
            cin >> guess;
            cout << "\n";
        
            bool flag = false;
            for (int i = 0; i < selected.size(); i++) {
                if (selected[i] == guess) {
                    display.replace(i*2, 1, 1, guess);
                    flag = true;
                }
            }
            if (!flag) {
                cout << "\nNay!\n";
                cout << "\n";
            } else {
                cout << display;
            }
        
        }
        

        【讨论】:

        • 其实不会的;这仅适用于第一个字符。但是您需要跟踪并显示所有猜测的字符
        猜你喜欢
        • 2011-06-08
        • 1970-01-01
        • 2013-04-01
        • 2010-12-06
        • 2013-05-26
        • 1970-01-01
        • 1970-01-01
        • 2019-01-24
        相关资源
        最近更新 更多