【问题标题】:Can't understand why I can't loop %[^/n]不明白为什么我不能循环 %[^/n]
【发布时间】:2018-11-07 13:35:50
【问题描述】:

我似乎无法在这里找到问题所在。

在第一个循环中,我可以输入债权人的姓名,但在第二个循环中我不能这样做。

int main(){
    float cb,ir,si,sum=0,totaldebt;
    int time,i;
    char name[25];
    printf("------------Welcome to Debt Management System-------------");

    for (i=1;i>=1;i++){
        printf("\n%d)Name of the creditor: ",i);
        scanf("%[^\n]",&name);
        printf("Enter your current balance: ");
        scanf("%f",&cb);
        printf("Enter its interest rate: ");
        scanf("%f",&ir);
        printf("Enter time for the loan: ");
        scanf("%d",&time);
        si=cb*ir*time/100;//simple interest
        totaldebt=si+cb; //simple interest + current balance

        if (name=='none'){
            break;
        }
    sum+=totaldebt;
}

它跳过了scanf 部分,我有点猜想阅读部分似乎被之前的阅读卡住了。

【问题讨论】:

  • 需要一些minimal reproducible example:例如name是什么?
  • 您希望scanf("%[^\n]*c",&name); 匹配什么? Scanf 模式不是正则表达式; *c 都只会匹配它们自己(这肯定会失败)。
  • 人...你在评论区回答!
  • 忘记添加初始化对不起..

标签: c loops scanf


【解决方案1】:

要获得您想要的效果,%[^\n]*c 应该是 %[^\n]%*c。您需要第一个模式的说明符,然后是单个字符的说明符。您现在编写它的方式是要求scanf 将所有内容匹配到换行符,然后读取序列*c

它无法读取该序列,但它匹配第一个说明符。因此,您最终会得到一个未使用的换行符,这可能会影响您的其他输入。

还有你的for (i=1;i>=1;i++) 的潜在问题,这种情况很可疑,可能会持续一段时间。

现在,虽然这可能是一个有趣的练习,但我建议你放弃scanf 并切换到fgets 来阅读输入行。它不那么神秘,它会强制你传递一个缓冲区大小,与scanf 相比,这使得使用它更容易、更安全。

【讨论】:

  • "应该是 %[^\n]%*c" --> scanf("%[^\n]%*c",name);类似于gets(name);,两者都不应该使用。
  • @chux - 不太像gets,因为scanf("%25[^\n]%*c",name),但没有没有方法可以让gets 安全。此外,我认为fgets 是任何地方的绝佳选择。
  • scanf("%25[^\n]%*c",name) 也不安全,它可能会溢出char name[25];,并且在输入"\n" 之类的角盒时也会遇到问题,从而使name[] 未分配。是的fgets() 更好,但随后要求fgets() 与其他输入一起在scanf("%d",&time); 之后做一些事情来消耗\n - 这是这里的建议 - 但IMO,对于所有行都不清楚。
  • @chux - 你知道你可以发布另一个答案,对吧?
【解决方案2】:

为了完成第一个答案,我注意到了这个问题:

if (name=='none')
{
    break;
}

这种形式在 C 中是不正确的,你应该:

  • 使用strcmp 函数,
  • 使用"而不是'来定义一个字符串:


/* if two strings are the same --but not necessary at the same adress-- strcmp return 0*/
if (0 == strcmp(name, "none"))
{        
    break;
}

【讨论】:

  • 您也可以使用if(!strcmp(name, "none")),因为0 在条件语句中的处理方式与false 相同
  • @Tau:最好使用左侧带有strcmp() 的显式关系运算符,因为运算符反映了比较正在进行的测试。也就是说,strcmp(a, b) == 0 测试相等,strcmp(a, b) >= 0 测试a 是否大于(排序后)b,等等。当然,比较总是与0。
  • if (name == 'none') 中缺少strcmp() 只是问题的一半。另一半是 'none' 不是 C 字符串常量,而是字符常量(而且相当奇怪):Live Demo on ideone。 (也就是说,我忽略了 char*char 的比较 - 我想知道编译器是否接受了它。令我惊讶的是,它接受了。)
【解决方案3】:

在接受字符串输入时,您不需要使用引用运算符“&”。这就是为什么在您的第一个 scanf 语句中使用 name 而不是 &name。如果要在输入中使用换行符,也可以使用 %*c 修改输入语句,如下所示。其他错误已在上述答案中说明。 scanf("%[^\n]",name);或者 scanf("%[^\n]%*c",name);

【讨论】:

    猜你喜欢
    • 2019-05-16
    • 2016-01-24
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    • 2019-06-10
    相关资源
    最近更新 更多