【问题标题】:How do I ignore certain scan calls when using scanf() in C? (READ BODY)在 C 中使用 scanf() 时如何忽略某些扫描调用? (阅读正文)
【发布时间】:2021-10-31 01:44:11
【问题描述】:

如果标题有误导性,我深表歉意,因为我不知道从哪里或如何开始。

最近我写了一个数学游戏,可以生成随机数并将它们转换为方程式。但是,如果我想让show-stats 之类的命令显示您的统计数据,程序所能做的就是接受数字。我必须编写命令,然后在后面输入一个数字才能让命令像这样被识别

show-stats 0
score is 1

show-stats
0             //number is required for some reason
score is 1

这是我写的一个小例子

#include <stdio.h>
#include <string.h>

int main() {
 int bar;
 char foo[]="";
 int score = 1;
    
 scanf("%s%i",foo,&bar);
 if(strcmp(foo,"show-stats"))
 {
  printf("Score is %i",score);
 }
 
 if(bar == 2)
 {
  score = bar*2;
  printf("Doubled Points.\n");
 }
}

这是实际代码,以备不时之需。另外,我想要关于实际代码的顾问,比如它的意大利面或某些东西是否消耗性能,或者如果它不是太麻烦的话,我一般可以改进什么。在此先感谢,我愿意接受建议。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#define VER 10
#define DIV "-----"

int main()
{
 system("clear");
 
 unsigned int x,y;                                                                                                                                                                   //equation numbers
 int ans,sum;                                                                                                                                                                        //user answer
 unsigned int max = 10;                                                                                                                                                              //max possible number that can be made, cannot go under 10.
 int score;                                                                                                                                                                          //what do you think?
 char operation;
 int correctAnswers = 0,wrongAnswers = 0;

 printf("Math game\nVersion %i.\n",VER);
 for (; ;)
 {
   //phase 1; make numbers.
   srand(time(NULL));
   x = rand() % max;
   y = rand() % max;
   //phase 2; make operation type.
   operation = rand() % 2;
   switch (operation)
   {
    case 0:operation = '+';sum = x + y;break;
    case 1:operation = '-';sum = x - y;break;
   }
   //phase 3; write question to console and get user answer
   printf("What is %i %c %i? ",x,operation,y);                                                                                                                                       //get input
   scanf("%i",&ans);
   //phase 4; determine right answer
   if (ans == sum)
   {
    score++;
    correctAnswers++;
    max++;
    printf("Your correct! +1!\n");
    printf("%sStats%s\nScore:%i\nMax possible number:%i\nCorrect Answers:%i\nWrong Answers:%i\n%s%s%s\n",DIV,DIV,score,max,correctAnswers,wrongAnswers,DIV,DIV,DIV);                   //print stats when user wins,is a seperate call for readability. same thing on line 53 but for loss
   }
   
   else
   {
    score--;
    wrongAnswers++;
    if(max>10){max--;};                                                                                                                                                              //assures max doesn't go under 10
    printf("Wrong! -1\n");
    printf("%sStats%s\nThe correct answer was %i\nMax possible number : %i\nScore : %i\nCorrect Answers : %i\nWrong Answers : %i\n%s%s%s\n",DIV,DIV,sum,max,score,correctAnswers,wrongAnswers,DIV,DIV,DIV);
   }
 }
}

【问题讨论】:

  • 第一件事,从不使用scanf()读取用户输入而不检查返回值。一般建议是使用fgets() 读取完整的输入行,然后使用更丰富(且不易出错)的库进行解析,例如strtol().
  • char foo[]=""; 你觉得用scanf读取字符串时这个数组能容纳多少个字符?提示:不能!
  • @cs07 你知道什么是函数,什么是函数返回值吗?
  • 您的最小示例与您的实际代码有何关系?您没有在第二个 sn-p 中读取任何字符串。
  • 阅读 scanf 的手册页是个好主意

标签: c string scanf


【解决方案1】:

感谢 DevSolar,我知道该怎么做。使用fgets()strtol() 您可以收集整个字符串,并将其解析为命令和数字,我在这里阅读了strtol https://www.tutorialspoint.com/c_standard_library/c_function_strtol.htm

编辑:

char str[30] = ""; //the string the user types
   fgets(str,30,stdin);
   char *ptr; //the part of the string turned into words
   long ret; //the part of the string turned into numbers

   ret = strtol(str, &ptr, 10); //parameter 1;source string that is parsed;//parameter 2; string part of source.//parameter 3; base
   printf("The number(unsigned long integer) is %ld\n", ret);
   printf("String part is |%s|", ptr);

【讨论】:

  • 请注意,对于fgets,您还需要一个足够大的缓冲区来容纳一些输入。您的问题缓冲区根本无法容纳任何输入。它只能保存终止的 0 字节。
  • 您发布的有关函数strtol 的链接省略了有关函数行为的许多重要细节。例如,它没有指定如何检查转换错误或范围错误。我建议您改用this link from cppreference.com
  • @AndreasWenzel 是的,这就是为什么我花了这么长时间来进行编辑,因为它没有很好地描述任何东西,所以我只是在网上修改 gdb 直到我知道他们做了什么,我给这个读完
  • 您的代码仍有两条路径可能会失败:1) fgets() 可能会失败,返回 NULL。 2) 输入可以不是数字开头(返回0 并设置ptr = str)。 3) 输入的数量可能太大而无法放入ret(返回LONG_MAX / LONG_MIN 并设置errno = ERANGE)。我知道检查这些对于某些实验性代码来说似乎有些矫枉过正,但养成检查任何可能错误的习惯很重要。
  • 很抱歉迟到了 4 小时后我打了个盹,但无论如何我不知道 fgets 可能会失败,尽管我确实知道输入可以从其他东西开始,在这种情况下我只是采取了懒惰的路线并写道“如果您想使用命令并回答问题,请将命令放在答案之前”
猜你喜欢
  • 1970-01-01
  • 2013-04-23
  • 1970-01-01
  • 2021-07-10
  • 1970-01-01
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 2013-08-10
相关资源
最近更新 更多