【问题标题】:C program freezes after scanf inputC程序在scanf输入后冻结
【发布时间】:2015-01-29 07:35:31
【问题描述】:

我正在做一项家庭作业,以计算用户选择的第 n 个素数。我让它工作得很好,而且相当快,但是如果用户输入大于 50000 的值,我决定添加一条错误消息。出于某种原因,它决定不起作用,所以我把它拿出来了。之后,一旦用户输入他们想要的素数,我的程序就会冻结。

#include <stdio.h>

int main(void) 
{   
    long int pFactor,test,nthCount,target,result,notPrime;
    test=2;
    nthCount=0;
    printf("Which prime number do you want to know?");
    scanf("%li",&target);
    while (nthCount<target)
    {   
        for(pFactor=test/2;pFactor>1;pFactor--)
        {
            notPrime=0;
            result=(test%pFactor);
            if(result==0)
            {
                notPrime=1;
                break;
            }
            if(notPrime!=1)
            {   
                nthCount++;
                notPrime=0;
                test++;
            }
        }
    }
    test--;
    printf("The %li prime number is %li.\n",target,test);
    return 0;
}

我认为这与 scanf 相关,因为在那之后我尝试打印的任何内容都不会出现。

【问题讨论】:

  • 我在您发布的代码中看不到任何包含。你没有吗?您是否尝试添加打印语句来指示程序在“冻结”时实际在做什么?您是否尝试过使用调试器(带有断点等)?
  • 你考虑过无限循环的可能性吗?
  • 只是 stdio.h。抱歉,我一定没有抄袭。
  • 所以如果result==0,那么你打破了内部循环,但nthCounttarget没有改变,所以你的外部while循环将永远旋转......
  • 另外,我有义务说:请避免使用scanf。众所周知,它很难使用。首选使用fgetssscanf 的组合。 c-faq.com/stdio/scanfprobs.html

标签: c scanf


【解决方案1】:
for(pFactor=test/2;pFactor>1;pFactor--) // where test = 2

推论,pFactor>1总是false (1>1)

因此,流永远不会进入for 循环,因此nthCount 始终保持0

while (nthCount<target) // becomes an infinite loop

【讨论】:

  • 谢谢,我还没有意识到这一点。我将其修复为 >=,但是,我仍然面临同样的问题。我的 scanf 执行后什么都没有。
  • 在这里检查你的逻辑:: result=(test%pFactor); 这里,test = 2,pFactor = 1,所以,结果总是 = 0,因此,你将转到 if(result==0) 条件和 break from那里。因此,while 循环再次变为无限。
  • 这与我之前使用的代码完全相同,或者至少是相同的算法。我更改了几个变量名以使其更有意义,但除此之外,循环函数没有改变。它工作得很好。我还尝试在 scanf 之后但在循环之前插入打印语句,这些语句没有打印。
【解决方案2】:

您的程序陷入了无限循环。对于所有情况,for 循环的主体都无法访问,这会导致 while 循环无限运行。修改程序,下次自己调试程序。

【讨论】:

    【解决方案3】:

    在这种情况下(程序冻结),您通常可以通过进行一些观察来快速找到问题的根源。

    首先,确定是无限循环还是某些函数阻塞了程序流程。 100% CPU 使用率是一个失控循环的良好指标,0% CPU 使用率是一个良好指标,表明您的程序正在阻塞,即正在等待某个事件发生。在您的情况下,您可能已经注意到它是第一个:无限循环。

    然后尝试找出发生这种情况的位置和原因。例如,您可以在可疑循环中的关键位置添加调试输出。你可以调整你的循环体来适应这个:

    while (nthCount<target)
    {   
        /* added debug output: */
        printf("%ld, %ld, %ld\n", target, nthCount, pFactor);
        for(pFactor=test/2;pFactor>1;pFactor--)
        {
            /* omitted for the sake of brevity */
        }
    }
    

    运行这个,你会看到这样的:

    $ gcc test.cc && echo 1 | ./a.out | head
    Which prime number do you want to know?1
    1, 0, 0
    1, 0, 1
    1, 0, 1
    1, 0, 1
    1, 0, 1
    1, 0, 1
    1, 0, 1
    1, 0, 1
    1, 0, 1
    

    在这里你可以看到外循环无限旋转,因为内循环永远不会执行(最后一个数字总是小于或等于一),因此外循环的循环条件永远不会改变(因此永远不会错误) .这是您可以开始修复它的地方。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      • 2020-10-11
      相关资源
      最近更新 更多