错误:字符串常量之前的预期声明说明符或'...'[puts()和gets()语句错误

时间:2017-07-16 10:49:44

标签: c error-handling compiler-errors gets puts

编译我的Dice Roll程序后,我收到了这个错误。代码有什么问题?

在我使用gets()而不是scanf()命令之前,但由于这个原因我得到了这个错误 - 传递'gets'的参数1使得整数指针没有强制转换 所以我删除了gets()命令并使用了scanf,然后没有关于scanf()的错误。

获取这两个错误的原因是什么?

好的,所以根据答案,我知道我应该如何使用gets()命令以及为什么我不应该使用它而应该使用scanf()。所以,我做了改变。 虽然我遇到了两个新错误,但这次它与我使用的delay()命令有关。

错误:未定义的延迟引用         | error:ld返回1退出状态|

好的,所以我通过使用来自windows.h库而不是Delay()命令的Sleep()命令解决了我的上一次错误。这些节目已经编制完成 但是程序中仍然存在运行时错误,它在获取roll1之前一直运行良好,但它只是打印下两个语句并终止程序而不需要输入猜测。

它跳过printf("Will it be Higher/Lower or the same? (press H/L/S)\n");之后的所有代码并直接终止程序。

好的所以我解决了上面的问题,在"%c"语句中的scanf(" %c", &nextGuess);之前添加了一个空格。 (小事xD) 现在唯一的问题是我的toupper()命令无效。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <windows.h>


int main()
{
    int i, roll1=0, roll2=0, NumberOfRolls, RandomNUM1[50], RandomNUM2[50];
    char nextGuess;

    puts("Welcome to the Dice Roll Game");
    puts("How many times do you want to roll a dice?");
    scanf("%d", &NumberOfRolls);

    for( i=1; i<=NumberOfRolls; i++ ) {
        RandomNUM1[i] = ( rand()%6 ) + 1;
        roll1 += RandomNUM1[i];
    }

    printf("\nYou Got %d in your first roll!\n", roll1);
    Sleep(3000);
    printf("\nLet's see if you can guess the value of next roll.\n");
    printf("Will it be Higher/Lower or the same? (press H/L/S)\n");
    scanf(" %c", &nextGuess);
    toupper(nextGuess);

        for( i=1; i<=NumberOfRolls; i++ ) {
        RandomNUM2[i] = ( rand()%6 ) + 1;
        roll2 += RandomNUM2[i];
    }

    if(nextGuess=='H'){
        if(roll1<roll2){
            printf("You are such a player, you guessed it right! It's %d", roll2);
        }
        else if(roll1>roll2){
            printf("Uh-Oh! Bad Luck! First roll was higher, It's %d", roll2);
        }
        else if(roll1==roll2){
            printf("Uh-Oh! Bad Luck! Both the rolls are same, It's %d", roll2);
        }

    }

    if(nextGuess=='L'){
        if(roll1>roll2){
            printf("You are such a player, you guessed it right! It's %d", roll2);
        }
        else if(roll1<roll2){
            printf("Uh-Oh! Bad Luck! First roll was lower, It's %d", roll2);
        }
        else if(roll1==roll2){
            printf("Uh-Oh! Bad Luck! Both the rolls are same, It's %d", roll2);
        }

    }

    if(nextGuess=='S'){
        if(roll1==roll2){
            printf("You are such a player, you guessed it right! It's %d", roll2);
        }
        else if(roll1>roll2){
            printf("Uh-Oh! Bad Luck! First roll was higher, It's %d", roll2);
        }
        else if(roll1<roll2){
            printf("Uh-Oh! Bad Luck! Second roll is higher, It's %d", roll2);
        }

    }

        return 0;
}

2 个答案:

答案 0 :(得分:0)

gets函数从stdin读取一个字符串(直到下一个换行符),因此它要求一个char指针(char*)到一个可以放入的内存区域所有字符读取包括字符串终结符。你犯的错误是向该函数传递一个指向int的指针,因此不仅会出现编译器错误,因为你试图将一个int指针传递给gets(没有隐式转换),但即使它编译了,它也不会按预期工作,因为它会放置所有字符(大小为 一个字节 - 大部分时间)在内存区域编码为字符。这意味着当你尝试使用指向int的指针取消引用时,字符是&#34;读取就像它们是int&#34;!

有一个例子(假设1字节字符,4字节int和一个小端字段机器,并且存在从int *到char * 的隐式转换,它不存在并且希望永远不会存在):

int num
gets(&num);

如果我在stdin中输入123,则num的内存区域指针足够大以包含字符串,但它将包含(十字形表示):

0x31|0x32|0x33|0x00

因为该字符串长度为3个字符,所以&#39; 1&#39;的ASCII代码对于&#39; 2&#39;是0x31是0x32,对于&#39; 3&#39;是0x33并以&#39; \ 0&#39; 结束! 然后,当你尝试取消引用它时,你得到这个int(二进制表示 - 假设一个小端程序机器):

00000000|00110001|00110010|00110011

int值123,而是3224115。哪个你想得到什么。

使用scanf函数时,将格式字符串传递给该函数,告诉它如何解释传递给它的下一个参数并执行字符串读取到您指定的正确类型之间的适当转换。这意味着你在编写格式字符串时仍然应该注意你对scanf函数所说的内容(如果你告诉它读取一个字符串并向它传递指向int的指针,程序可能会崩溃) ,但如果正确编写格式字符串,它会为您执行适当的转换。

这就是scanf一切运作完美的原因(你正在阅读一个int而你指定&#34;%d&#34;作为格式字符串),而{{1}它不能编译以避免严重错误

我还想谈谈这个答案的一些要点:

  • 该示例仅用于说明目的,并且提供的代码不起作用。我所谓的它编译的事实是出于教学目的;显然,该示例中提供的代码无法编译
  • 如果在这个例子中,我们输入一个大于3个字符的字符串(如果包含空终止符则为4)或者int(char)类型包含少于(多于)4(1)字节的字符串,程序将已经崩溃,因为我们损坏了其他内存区域
  • 该参考资料在技术方面比我更专业,所以这里是指向gets函数和gets函数的链接:getsscanf(以及ASCII Table也很有用)
  • 您可以将scanf函数与gets函数一起使用来解析从atoi读取的字符串(使用char指针指向足够大的内存空间以包含字符串,这很难分配(*)到gets,但int是最好的方法。

(*)请记住:如果你分配一个包含20个字符的内存区域,用户将输入21个字符。 atoi函数失败,但最糟糕的是你有一个缓冲区溢出(如果你的程序在root权限下运行,则可能是一个高安全性问题)。

答案 1 :(得分:0)

你有一个迷路,

main的第2行,您声明char nextGuess,而不是char nextGues;

编译器会在,之后告诉您它需要说明符或......所以要么添加这些,要么使用;正确结束行

对于你提到的另一个问题:

  

传递&#39;的参数1得到&#39;从没有强制转换的整数生成指针

由于gets参数应该是char *str而你没有提供它

您可以通过以下方式解决此问题:

char tmp_NumberOfRolls[10];
gets(tmp_NumberOfRolls);  
NumberOfRolls = atoi(tmp_NumberOfRolls);

但我更喜欢scanf解决方案

PS ***//Error Line***不是评论(至少不是全部),因为***仍被视为代码的一部分,并会导致错误。将//向左移动一点或用/* ... */

将整个部分括起来