C 对石头/布/剪刀感到沮丧

C 对石头/布/剪刀感到沮丧,c,user-defined-functions,C,User Defined Functions,我还在和我叔叔一起学习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",

我还在和我叔叔一起学习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;
这是主.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]

它仍然抱怨我没有使用变量“choice”,但老实说,我不知道如何使用choice。 我可能不清楚这一点,但我没有直接“写”这一点。当我叔叔写的时候,我建议,然后在“课”结束后,我在我的机器上重写它。我真的不想完全理解我在这里做什么。。。该程序应该是显而易见的人有很多经验的编码。。。但我想我不明白

它应该选择玩石头/布/剪刀,并让计算机自己玩。else if语句,我们使用enum来指定选项,然后选择_to_int获取用户输入并将其转换回与enum匹配的值,并允许我基于这些值的比较创建“win/lose/draw”语句。我可能提出了一些愚蠢的方法来实现这个想法,但这就是我的想法。我还没有达到我可以创建赢/输/平局语句的程度,或者如果用户决定放入不符合游戏格式的内容(例如Z或其他内容)时处理错误的程度


感谢您迄今为止的帮助,并与我一起参与了这项可能是不必要的复杂的石头/布/剪刀实施

我不擅长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 );
}

和error main.c:104:1:error:isoc禁止嵌套函数[-Werror=pedantic]int choice\u to\u intconst char a也与缺少括号有关,因为编译器认为它仍然在前面的函数start\u play中,除了已经说过的:

那么看看这个,

int choice_to_int(const char a) 
{
   int r;
   switch ( r ) {  ... }
  /* .... */
}
您正在打开一个未初始化的变量!删除int r;并将函数更改为 int choice_to_intconst char r{…}您还忘了正确关闭缺少“}”的函数

void start_play( )

一些一般性建议:与其写100行有几十个问题的代码,不如一次写一小段代码,检查所有代码是否正常工作,然后继续写下一段代码

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

应该是:

int gen_hand(void);
void start_play(void);
void表示函数不带参数;空括号意味着我们还不知道需要多少时间,如果你做得不对,你的程序可能会出错

接下来,扫描%1s,回答;和扫描%1s,人手[0];。使用scanf,您必须告诉它在哪里写入您读取的字符。相反,你告诉它这些东西的当前价值。使用&operator获取目标位置的地址

在此代码中:

if(player_1==3){
  fprintf( stderr, "Player 1 entered an invalid hand choice, %s", player_1 );
/*          err_hand();
      break;} */
您从未关闭{因为您注释掉了关闭}。您不应该注释掉中断;}因为这意味着您将继续使用3作为数组索引,这超出了范围


在printf player two=>%d\n%2s,player_2,rps[player_2];,2表示:打印至少2个字符。所有字符串都比2长得多,因此这没有效果。你想干什么?

这是我见过的最好的标题。检查了你的个人资料,说你是作家。好奇的是,如果你不打算在低水平上编程,为什么C:?@Andro47我认为这是一个三重答案,首先,大多数作家都不以写作为生,至少不以写作为开始,其次,我写的小说,我最终想涉足游戏之类的特许经营作品,因此,学习编写C和其他语言将有助于我与直接处理这一方面的人合作,第三部分是,这不完全是我的想法。我请我叔叔教我编码,这是他认为最好的。到目前为止,我发现很难理解……很遗憾,我不能勾选多个答案,因为有几个答案是他写的
lped清除了最初的错误,但我仍然没有让它完全正常工作…据我叔叔所说的,%2s,在s开头放置2会将您要求它打印的字符移动2个空格,尽管我可能误解了。2是最小字段宽度。这意味着如果字符串短于2,那么它将打印2个字符,但仍保留空格。但是,如果字符串长度大于2,则这没有什么区别。如果要打印2个空格,则只需在%.true之前放置两个空格,他应该有“return”语句而不是赋值语句。
if(player_1==3){
  fprintf( stderr, "Player 1 entered an invalid hand choice, %s", player_1 );
/*          err_hand();
      break;} */