程序是一个井字游戏,取用户的X和Y值后就挂了
这是主文件:
#include <stdio.h>
#include <string.h>
#include "input.cpp"
int makeMove(char** board, char* moveX, char* moveY, char playerMove) {
printf("Make your x move: ");
int answerX = (int)getNum(moveX, 2);
printf("Make your y move: ");
int answerY = (int)getNum(moveY, 2);
answerX--;
answerY--;
if ((answerX < 0) || (answerX > 2)) {
return -1;
}
if ((answerY < 0) || (answerY > 2)) {
return -1;
}
board[answerY][answerX] = playerMove;
return 0;
}
int main()
{
int turns = 0;
const int MAX_TURNS = 9;
char playerOneChar = 'X';
char playerTwoChar = 'O';
char currentChar = playerOneChar;
while (turns <= MAX_TURNS) {
char board[3][3];
memset(board, ' ', 9);
char moveX[2];
memset(moveX, ' ', 2);
char moveY[2];
memset(moveY, ' ', 2);
int result = makeMove(board, moveX, moveY, currentChar);
if (result == 0) {
if (currentChar == playerOneChar) {
currentChar = playerTwoChar;
}
else {
currentChar = playerOneChar;
}
turns++;
}
else {
printf("Player move was out of bounds.");
}
}
}
这是 input.cpp,它旨在安全地从用户那里获取数字,而不允许 对于缓冲区溢出或其他问题:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
long getNum(char* buffer, int bufferSize)
{
long answer;
int success = 0;
while (!success)
{
// This gets the input from the user
if (!fgets(buffer, bufferSize, stdin))
{
//If fgets fails, return with exit code 1.
return 1;
}
char* endptr;
errno = 0;
answer = strtol(buffer, &endptr, 10);
// If an error occurs, the user is told the number is too small or large.
if (errno == ERANGE)
{
printf("Sorry, this number is too small or too large.\n");
success = 0;
}
else if (endptr == buffer)
{
success = 0;
}
else if (*endptr && *endptr != '\n')
{
success = 0;
}
else
{
success = 1;
}
}
return answer;
}
我尝试输入2个数字,但之后程序挂了。我试图在 Internet 上进行研究,但对于为什么函数无法正确写入 2D 数组的原因缺乏任何解释。我假设它挂起是因为 char** 是指向 char* 的指针,而不是指向二维字符数组的指针。
makeMove()
的第一个参数需要是char board[][3]
,这是一个固定的二维数组,行长为3,与您在main()
中声明的相匹配。 char** board
是一个相当不同的东西,它是一个 pointers 数组,每个指针指向一个 char
s 的一维数组。
这个函数声明
int makeMove(char** board, char* moveX, char* moveY, char playerMove) {
无效。
你正在传递给函数
int result = makeMove(board, moveX, moveY, currentChar);
二维数组
board
声明为
char board[3][3];
用作参数表达式,它被隐式转换为指向其类型
char ( * )[3]
的第一个元素的指针。但是函数参数的类型是char **
。 char ( * )[3]
和 char **
指针类型的对象之间没有隐式转换。所以这个函数调用已经调用了未定义的行为。
你应该像这样声明函数
int makeMove(char board[][3], char* moveX, char* moveY, char playerMove) {
另一个问题是
fgets
的调用
if (!fgets(buffer, bufferSize, stdin))
由于
bufferSize
等于 2
那么换行符 '\n'
将不会存储在输入缓冲区中(只有当用户立即按下 Enter 键时才会存储。在这种情况下,数组看起来像{ '\n', '\0' }
)。因此,后续调用 fgets
将读取一个空字符串,该字符串将仅包含换行符。
注意好像是因为文件的扩展名
#include "input.cpp"
您正在将程序编译为 C++ 程序。 C和C++是两种不同的语言。但无论如何,将模块作为标头包含在内是一个坏主意。你需要单独编译它。