【问题标题】:Frustrated with Rock/Paper/Scissors对石头/纸/剪刀感到沮丧
【发布时间】:2014-07-21 10:08:05
【问题描述】:

我还在和我叔叔一起学习 C,我在尝试编译我们一起编写的玩石头剪刀布的程序时遇到了另一个问题。我在程序上还有更多工作要做,但我什至无法让大部分事情正常工作。

我使用 Make 命令从编译器收到的错误

main.c: in function 'start_play':

main.c:79:7: error: format '%s' expects argument type 'char *', but argument 2 has type 'int' [-werror=format=]

scanf("%1s", human_hand[0]);


main.c:82:11: error: format '%s' expects argument of type 'char *', but argument 3 has type 'int' [-Werror=format=]

fprintf( stderr, "Player 1 has entered an invalid hand choice, %s.", player_1);

main.c:104:1: error: ISO C forbids nested functions [-Werror=pedantic]

int choice_to_int(const char a)

main.c:104:1: error: ISO C90 forbids mixed declarations and code [-Werror=pedantic]

main.c 132:1: error: expected declaration or statement at end of input

}

main.c:132:1: error: expected declaration or statement at end of input

main.c:60:6: error: unused variable 'choice' [-Werror=unused-variable]

enum choices choice;

这是 main.c 文件的内容,我似乎无法正确理解。

/*
Programmer: Tim Bowen
Creation Date: 2014/05/26
Last Updated: 2014/05/27
Project Name: RPS(Rock/Paper/Scissors)
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


int gen_hand( );
void start_play();
int choice_to_int(const char a);


int main ( int argc, char *arga[], char **env)
{    
  start_play( );    
  return 0;    
} /*end main*/


/*
Precondition: Srand must but initialized before usage of gen_hand
Post condition: function returns either 0, 1 or 2.
*/ 


int gen_hand( ) {
  return((rand() % 3 ));
}

void start_play( ) {

  enum choices { ROCK, PAPER, SCISSORS };
  enum choices choice;
  const char *rps[] = {"Rock", "Paper", "Scissors"};
  int player_1, player_2;
  char answer[2];
  char human_hand[2];
  srand(time(NULL));

  printf("%s\n", "This program plays Rock, Paper, Scissors.");
  printf("%s\n", "Version 0.2");

  do{
    printf("%s\n", "Do you want to play against the computer? (Y/N):");
    printf("%s\n", "Any other character to quit.:");
    scanf("%1s", answer);
    printf("%s\n", answer);
    break;
    if(answer[0] == 'y' || answer[0] == 'Y')
    {
      printf( "%s\n", "Please enter your hand(R/P/S):");
      scanf("%1s", human_hand[0]);
      player_1=choice_to_int(human_hand[0]);
        if(player_1==3){
          fprintf( stderr, "Player 1 entered an invalid hand choice, %s", player_1 );
/*          err_hand();
          break;} */
      player_2=gen_hand( );
      printf( "Player one => %d\n %2s", player_1, rps[player_1]);
      printf( "player two => %d\n %2s", player_2, rps[player_2]);
    }
    else if (answer[0] == 'n' || answer[0] == 'N' )
    { 
      player_1=gen_hand( );
      player_2=gen_hand( );
      printf( "Player one => %d\n %2s", player_1, rps[player_1]);
      printf( "player two => %d\n %2s", player_2, rps[player_2]);
    }
    else {
      break;     
    }
  while (1);
  return;

}


/*
precondition: user passes in either, Rr, Pp, Ss, or another incorrect response.
post condition: function returns either 0, 1, or 2 for correct responses, or 3 for erroneous ones.
*/


int choice_to_int(const char a) 
  {

  int r;

  switch ( r ) {

    case 'R':
    case 'r':
    r=0;
    break;

    case 'P':
    case 'p':
    r=1;
    break;

    case 'S':
    case 's':
    r=2;
    break;

    default:
    r=3;
    break;

 }
return (r); 
} 

对于几乎过多的额外行,我深表歉意,但我这样做是为了(希望)更容易阅读。我不确定这次我做错了什么,因为我几乎完全从课堂上的笔记中复制了这一点。我无法继续尝试添加我应该添加的部分,因为我无法让我们一起编码的部分甚至正常工作。我叔叔编译的例子中没有出现这些错误。

编辑:到目前为止,给出的答案已经帮助清除了大部分涉及的错误,除了一个新错误:

main.c:58:5 错误:格式“%s”预期参数类型为“char ”,但参数 2 的类型为“char ()[2]”[-Werror=format ]

它仍然在抱怨我没有使用变量“选择”,但老实说,我不确定如何使用选择。 我可能不清楚这一点,但我没有直接“写”这个。我建议我叔叔写的时候,然后在“上课”结束后我在我的机器上重写它。我并没有真正声称完全理解我在这里所做的事情......该程序应该是显而易见的(对于具有丰富编码经验的人......)但我想我没有得到它。

它应该选择玩石头/纸/剪刀,并提供让计算机自己玩的选项(else if语句),我们使用枚举来指定选项,然后使用choice_to_int来获取用户输入并将其转换回与枚举匹配的值,并允许我根据这些比较创建“赢/输/画”语句。我可能建议了一些愚蠢的方法来实现这个想法,但这就是想法。我还没有达到可以创建赢/输/平局语句的地步,或者如果用户决定放入不适合游戏格式的东西(比如 Z 或其他东西),则可以处理错误。

感谢您迄今为止的帮助,感谢您在这方面的帮助,也许是石头/纸/剪刀的不必要的复杂实现......

【问题讨论】:

  • 我最近看到的最好的标题。
  • 查看了您的个人资料,说您是作家。只是好奇,如果您不打算在较低级别上编程,为什么是 C :)?
  • @Andro47 我认为这是一个三方面的答案,首先,大多数作家不以写作为生,至少不要开始,其次,我写的小说,我最终想分支进入游戏等特许经营工作,因此学习编写 C 和其他语言将有助于我与直接处理该方面的任何人合作的能力,第三部分是这并不完全是我的想法。我请叔叔教我编程,他认为这是最好的。到目前为止,我发现很难理解...
  • 很遗憾我不能勾选多个答案,因为几个答案有助于清除最初的错误,但我还没有完全工作......

标签: c user-defined-functions


【解决方案1】:

一些一般性建议:不要编写 100 行代码来解决几十个问题,而是一次编写一小段,检查它是否正常工作,然后再进行下一段。

其他答案尚未提及的问题:


int gen_hand( );
void start_play();

应该是:

int gen_hand(void);
void start_play(void);

void 表示该函数不带参数;空括号表示我们还不知道它需要多少(如果你做的不对,你的程序可能会搞砸)。


接下来,scanf("%1s", answer);scanf("%1s", human_hand[0]);。使用scanf,你必须告诉它在哪里写你读到的字符。相反,您是在告诉它这些事物的当前值。使用&amp; 运算符获取目标位置的地址。


在这段代码中:

if(player_1==3){
  fprintf( stderr, "Player 1 entered an invalid hand choice, %s", player_1 );
/*          err_hand();
      break;} */

您永远不会关闭{,因为您注释掉了关闭}。您不应该注释掉break;},因为这意味着您继续使用3 作为超出范围的数组索引。


printf( "player two =&gt; %d\n %2s", player_2, rps[player_2]); 中,2 表示:至少打印 2 个字符。你所有的字符串都比 2 长得多,所以这没有效果。你想做什么?

【讨论】:

  • %2s,据我叔叔所说,将 2 放在 s 的开头会使您要求它打印的字符移动 2 个空格,尽管我可能会误会了。
  • 2 是最小字段宽度。这意味着如果您的字符串短于 2,那么它仍然会打印 2 个字符(左填充空格)。但是,如果您的字符串长于 2,那么这没有区别。如果要打印 2 个空格,则只需在 % 之前放置两个空格即可。
【解决方案2】:

我不擅长 C 但可能是这个字符串

fprintf( stderr, "Player 1 entered an invalid hand choice, %s", player_1 );

应该是

fprintf( stderr, "Player 1 entered an invalid hand choice, %d", player_1 );

而且你需要把变量为int的所有字符串都改成%d。

你忘记了一个右括号:

if(player_1==3){
      fprintf( stderr, "Player 1 entered an invalid hand choice, %s", player_1 );
}

并且错误main.c:104:1: error: ISO C forbids nested functions [-Werror=pedantic] int choice_to_int(const char a) 也与缺少括号有关,因为编译器认为它仍在以前的函数中(start_play())

【讨论】:

    【解决方案3】:

    除了已经说过的话:

    看看这个:

    int choice_to_int(const char a) 
    {
       int r;
       switch ( r ) {  ... }
      /* .... */
    }
    

    您正在打开一个未初始化的变量!去掉int r;,把函数改成
    int choice_to_int(const char r) {...}你也忘了正确关闭函数(缺少'}')

    void start_play( )
    

    【讨论】:

    • 是的,他应该有'return'语句而不是赋值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 2020-06-20
    • 2013-12-09
    • 1970-01-01
    • 2014-11-21
    • 2015-01-15
    相关资源
    最近更新 更多