【问题标题】:How to check for an empty character pointer in C如何在C中检查空字符指针
【发布时间】:2022-01-05 19:36:38
【问题描述】:

我最近正在使用 C 在终端上开发简单的国际象棋游戏,但在获取用户输入方面遇到了一个小问题。

以下函数接受一个包含当前棋子位置的 3 维数组、一个指向将包含用户输入的缓冲区的指针,以及我设置为 7 的该缓冲区的大小。

void next_move(char board[8][8][4], char* move, size_t buff_size){
 
         char * move_1 = (char )malloc(sizeof(char)3);
         char * move_2 = (char )malloc(sizeof(char)3);
         char delim[]=" ";
 
         getline(&move,&buff_size,stdin);
 
         move_1=strtok(move,delim);
         move_2=strtok(NULL,delim);
 
         if(*move_1 == '\0'){
                 printf("invalid move !");
                 return ;
         }
 
         printf("%s%s\n",move_1,move_2);
          if(!check_move(board, move_1, move_2)){
                 printf("valid move !\n");
 
         }
}

函数 check_move 接收用户输入的两个移动并验证它们是否是有效的国际象棋移动(例如“Nb1 Nc3”)。

我的问题在于,当用户输入任何字符或不包含空格的字符串(strtok 中定义的分隔符)时,当我尝试进行检查时会导致分段错误:

if(*move_1 == '\0')

主要用于在move_1和move_2指针为空的情况下处理异常。

我有两个问题:

  1. 如何检查 char 指针是否为空? (我已经尝试过使用move_1 == NULL)
  2. 如果我将条件语句设置为if(*move_1 != 0),为什么代码会继续执行并返回。虽然这会导致所有输入(即使格式正确)都无效。

【问题讨论】:

  • 很好奇,为什么要为棋盘使用 3D 数组?写 3D 国际象棋?
  • sizeof(char)3 -- 这个错字出现在你的实际代码中吗?请注意提供Minimal, Reproducible Example。您的演员表也不正确(和not necessary)。将缓冲区重新分配给strtok 的返回值肯定会泄漏内存。
  • if(*move_1 == '\0') 更改为 if(move_1 == '\0')
  • 另外,如果 move_1 为 NULL,则不能为 move_2 调用 strtok。
  • 是的,如果您可以提供minimal reproducible example,您会得到更好的答案,因为这样我们就不必猜测可能出了什么问题,我们可以让您的代码在我们的在将其作为答案提交之前拥有自己的机器。

标签: c string pointers segmentation-fault char


【解决方案1】:

问题 1

听起来move 可能是 NULL,但您对 strtok 的第一次调用应该有一个非 NULL 指针。因此,在您致电getline 之后,我认为您应该检查以确保move 不为NULL。检查move_1move_2 是否不为NULL 也是一个好主意。您可以使用如下代码进行这些检查:

getline(&move,&buff_size,stdin);
if (move == NULL) {
  // handle this case, probably with an early return
}

请注意,上面的代码只显示了对move 的检查,但我认为您可能应该对move_1move_2 执行相同的操作,在您分配给它们之后,在您使用它们或取消引用之前他们。 (其中一些检查可能会在进一步调查后证明是不必要的,但目前我认为首要任务是修复所有分段错误,以便您的程序可以运行而不会崩溃。)

问题 2

听起来您将代码更改为以下内容,并开始将您的所有输入声明为无效:

if(*move_1 != '\0'){
  printf("invalid move !");
  return;
}

嗯,对此的解释很简单。你告诉你的编译器,如果move_1 字符串的第一个字符不是空终止字符,它应该打印“无效移动!”并返回。因此,只要move_1 不为空,它就会这样做。也许您打算使用==(等于)而不是!=(不等于)。

【讨论】:

  • 非常感谢您的及时回复 :) 问题确实在于 move_2 指针为 NULL。我确信问题出在 if 语句上,我没有费心检查 move_2 指针是否被调用,而没有在以后的函数调用中检查。第二个问题背后的逻辑也清楚了。
【解决方案2】:

如果您的意思是不输入您正在按 Enter 的字符,则意味着您的条件应该是:if(*move_1 == '\n'),因为在新行中输入 Enter 到命令行,它是 '\n' 转义字符。
我希望我能看到你的完整项目并共同努力完成它......

【讨论】:

  • 这只会处理没有输入的异常,而不检查 move_2 是否为空,这会在字符串没有空格的情况下导致分段错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-09
  • 2021-03-17
  • 1970-01-01
相关资源
最近更新 更多