C程序,得到关于未初始化变量的错误,程序永远不会结束

时间:2017-10-11 03:20:26

标签: c

#define _CRT_SECURE_NO_WARNINGS     
#include <stdio.h>                  
#include <ctype.h>                  
#define MAXGUESSES 5


void Instructions();


int PlayGuess(char solution);


char  GetLetter();


int CompareLetters(char guess, char solution);




int main()
{
    int i = 0;
    int numgames = 0;
    char solution;
    char guess;
    int compareletter(char guess, char solution);
    FILE *inp;
    inp = fopen("letterList.txt", "r");
    fscanf(inp, "%c", &solution);
    Instructions();
    //get number of games the user wants to play
    printf("Please enter the number of games you want to play\n");
    scanf("%d", &numgames);
    for (i = 1; i <= numgames; i++)
        //print current game (value of i)
    {
            //get letter to guess from file
            fscanf(inp, "%c", &solution);
            PlayGuess(solution);
            printf("\nThe letter is %c\n", solution);
    }


    fclose(inp);

}
void Instructions()
{
    printf("Welcome to Letter Guess\n");
    printf("To begin you will enter the number of games you want to 
play(1 – 4 games)\n");
    printf("You have 5 chances to guess each letter\n");
    printf("Let's begin\n");

}

int PlayGuess(char solution) //player defined guesses.
{
    int numGuesses = 0;
    int winOrLose = 0;
    while (numGuesses < MAXGUESSES)
    {
            GetLetter();

            numGuesses = numGuesses + 1;
            if (numGuesses>MAXGUESSES)
            {
                    printf("You have run out of guesses\n");
            }
    }


    return 0;
}


//get the guess from the user (call GetLetter function)
//call compareLetters function

char GetLetter()
{
    char guess = 0;
    char solution;
    printf("Enter a guess:", guess);
    scanf(" %c", &guess);
    CompareLetters(guess, solution);
    return guess;
}


//compare the guess and the solution
//return a 1 if they are the same
// message based on before or after alphabetically
//return a 0 if the guess and answer are not the same

int CompareLetters(char guess, char solution)
{
    if (guess == solution) //if answer is correct
    {   printf("Thats it!\n");
    return 1;
    }
    else
        if (guess<solution)
        {
                printf("The letter you are trying to guess comes after %c\n", guess);
                printf("\nTry again\n");
                GetLetter();

                return 0;
        }
        else
            if (guess>solution)
            { printf("The letter you are trying to guess comes before %c", guess);
    printf("\nTry again\n");
    GetLetter();
    return 0;
            }
}

很抱歉,如果代码有点混乱。

问题#1:变量“解决方案”未初始化但我不知道如何修复它。我有很多这个问题,如果可能的话我可以使用解释。

问题#2:当我启动程序并输入我想玩的游戏数量时,它会忽略它并给我无穷无尽的猜测,程序永远不会停止。

感谢。

3 个答案:

答案 0 :(得分:1)

  1. 只需添加char solution = '\0';。这足以摆脱警告。
  2. 尝试打印您刚刚在numgames函数中阅读的scanf()的值。由于某种原因,你似乎得到了一些无效的价值......
  3. 更新:我发现您的问题:您是从GetLetter()致电PlayGuess();你从CompareLetters()打电话给GetLetter();然后从GetLetter()调用CompareLetters(),这样就可以创建无限的递归。从GetLetter()删除来电CompareLetters()

答案 1 :(得分:0)

在函数中使用它们之前,必须先将guesssolution初始化为某些内容。

这行是什么

int compareletter(char guess, char solution);

表示,没有相同名称的函数,也不是对任何函数的调用。

如果是虚拟初始化,可以使用

solution = '\0';

答案 2 :(得分:0)

继续我的评论,你的代码中的关键要点是(1)你不能通过猜测语法来编译C,一遍又一遍地编译,(2)通过检查所有输入函数的返回并验证您收到的值来验证程序的所有输入,(3)启用编译器警告,然后阅读,理解并更正每个输入在再次尝试编译之前发出警告,并且(4)在完全编译之前不接受代码,而不会发出警告。

由于您的代码包含#define _CRT_SECURE_NO_WARNINGS,因此很明显您使用的是cl.exe(来自cmd.exe或来自VS-Code)的Windows。要学习基本编程,请关闭VS-Code,打开VS(或SDK)安装提供的命令行,不要再担心再次使用IDE,直到从命令行掌握编译并理解编译器为止选项。请参阅cl.exe C/C++ Compiler Options,或在命令提示符下键入cl /?

从命令行,您的基本编译字符串应类似于:

cl.exe /nologo /W3 /Ox /Tc mysource.c

/W3启用大多数警告,/Ox启用所有优化)

我发现使用.obj.exe文件不会弄乱我的c-source目录很有帮助,所以我为对象和可执行文件创建了两个额外的目录/obj/bin文件。然后使用/Fo/Fe选项告诉编译器将目标文件和exe文件放在适当的目录中,例如。

cl /nologo /W3 /Ox /Foobj/mysource /Febin/mysource /Tc mysource.c

这会将mysource.obj放在obj目录中,将mysource.exe放在bin目录中。

在坐在键盘后面开始啄食之前,你必须清除头脑中的代码逻辑。 (见上文(1))。通过为您的代码绘制一个简单的逻辑图并确定您将在main()中处理的值,然后在每个function()中处理的内容,最简单的方法是保持直线。你不需要任何花哨的东西,8.5x11的纸和铅笔都可以。在您清楚地了解代码的每个部分将会做什么之后,然后坐下来开始啄食。

将该逻辑用于测试,您可以重新编写代码,使其比现在更有意义,例如。

#define _CRT_SECURE_NO_WARNINGS     
#include <stdio.h>                  
#include <ctype.h>                  

#define MAXGUESSES 5

void Instructions();
int PlayGuess (char solution);
char  GetLetter();
int CompareLetters (char guess, char solution);

int main (void)
{
    int i = 0,
        numgames = 0;
    char solution;
    FILE *inp = fopen ("letterList.txt", "r");

    if (inp == NULL) {
        fprintf (stderr, "error: file open failed 'letterList.txt'.\n");
        return 1;
    }

    Instructions(); /* give instructions */

    /* get number of games the user wants to play */
    printf("Please enter the number of games you want to play: ");
    if (scanf ("%d", &numgames) != 1) {
        fprintf (stderr, "error: invalid input - numgames.\n");
        return 1;
    }
    putchar ('\n');

    for (i = 0; i < numgames; i++)
    {
        /* get letter to guess from file */
        if (fscanf (inp, " %c", &solution) == EOF || solution < ' ' 
                    || '~' < solution) {
            fprintf (stderr, "error: invalid character - solution.\n");
            return 1;
        }
        printf (" ==>  Game  %d  <==\n\n", i + 1);
        PlayGuess (solution);
        printf("The letter was '%c'!\n\n", solution);
    }
    fclose (inp);

    return 0;       /* main() is type int and returns a value */
}

void Instructions()
{
    printf ("Welcome to Letter Guess\n"
            "To begin you will enter the number of games you want "
            "to play (1 – 4 games)\n"
            "You have 5 chances to guess each letter\n"
            "Let's begin\n\n");
}

int PlayGuess (char solution)
{
    int numGuesses = 0;
    char guess;

    while (numGuesses < MAXGUESSES)
    {
        guess = GetLetter();
        if (CompareLetters (guess, solution))
            return 1;
        numGuesses = numGuesses + 1;
    }
    printf ("You have run out of guesses\n");

    return 0;
}


/* get a letter and validate it is good */
char GetLetter()
{
    char guess = 0, 
        tmp;

    printf ("Enter a guess: ");

    if (scanf (" %c", &tmp) != EOF && ' ' <= tmp && tmp <= '~')
        guess = tmp;

    return guess;
}


/* compare the guess and the solution
 * return a 1 if they are the same
 * message based on before or after alphabetically
 * return a 0 if the guess and answer are not the same
 */
int CompareLetters(char guess, char solution)
{
    if (guess == solution)      /* answer is correct */
    {   
        printf ("Thats it!\n\n");
        return 1;
    }

    if (guess < solution)
        printf ("The letter you are trying to guess comes after '%c'\n", 
                guess);
    else 
        printf ("The letter you are trying to guess comes before '%c'\n", 
                guess);

    printf ("Try again\n\n");

    return 0;
}

cl.exe(VS)的示例编译字符串

>cl /nologo /W3 /Ox /Foobj/guessletter /Febin/guessletter /Tc guessletter.c

示例使用/输出

> bin\guessletter.exe
Welcome to Letter Guess
To begin you will enter the number of games you want to play (1 – 4 games)
You have 5 chances to guess each letter
Let's begin

Please enter the number of games you want to play: 2

==>  Game  1  <==

Enter a guess: k
The letter you are trying to guess comes before 'k'
Try again

Enter a guess: c
The letter you are trying to guess comes after 'c'
Try again

Enter a guess: d
Thats it!

The letter was 'd'!

==>  Game  2  <==

Enter a guess: e
The letter you are trying to guess comes after 'e'
Try again

Enter a guess: g
The letter you are trying to guess comes before 'g'
Try again

Enter a guess: f
Thats it!

The letter was 'f'!

仔细研究并思考如何用C语言编程。这是一种精确的语言。由您来计算所有输入缓冲区中的所有字符以及内存使用情况。如果你不知道库函数采用什么参数,或者它将返回什么类型和值,或者如何使用它,请查阅它。手册页可在例如msdn fscanf, fwscanfscanf(3): input format conversion

如果您还有其他问题,请与我们联系。

在任何情况下接受输入,转换为小写

要在任何情况下接受输入并将值转换为小写,以便guess在代码中始终为小写,则只需更改一行:

/* get a letter and validate it is good
 * (convert letter to lowercase)
 */
char GetLetter()
{
    char guess = 0, 
        tmp;

    printf ("Enter a guess: ");

    if (scanf (" %c", &tmp) != EOF && ' ' <= tmp && tmp <= '~')
        guess = tolower (tmp);

    return guess;
}

注意:对于ASCII字符,第6位是&#39; case bit&#39;,如果是1,则字符为小写,{{1}大写。 0可以简单地写成:

tolower