【问题标题】:Special character reading in for loop issue in cc中for循环问题中的特殊字符读取
【发布时间】:2017-12-29 00:08:10
【问题描述】:

我的情况是我需要输入一些字符,并且在读取特定字符(此处为 *)后,我需要跳出循环。

代码:

void main()
{
    int i=0,temp=0;
    char a[100];
    printf("Enter the array\n");

    for(i=0;a[i]!='*';i++)
    {
        scanf("%c",&a[i]); 
    }
}

即使我输入了“*”字符,它也不会退出循环。

我更改了如下所示的代码,它可以正常工作。

void main()
{
    int i=0,temp=0;
    char a[100];

    printf("Enter the array\n");

    for(i=0;;i++)
    {
       scanf("%c",&a[i]);
       if(a[i]=='*')
           break;
    }
}

第一个代码有什么问题? 我正在使用 gcc 编译器。

【问题讨论】:

  • @James Z :代码没有问题,而且编译良好。但是问题来了,当我输入“*”时,它并没有从循环中出来。
  • @Rabbid76--您链接到的问题根本不是重复的。虽然换行符的处理是发布代码中的一个潜在问题,但这与这个问题中提出的问题无关。这里的实际问题与尝试使用未初始化变量的值(导致 UB)有关,这是由代码中的逻辑错误引起的。第二个示例以相同的方式处理换行符,OP 似乎对它的工作方式很满意。他们可能稍后会改变主意(当他们查看数组时),但这是一个不同的问题(这是您的重复问题)。

标签: c for-loop gcc char


【解决方案1】:
void main()
{
  int i=0,temp=0;
  char a[100];
  printf("Enter the array\n");

  for(i=0;a[i]!='*';i++)
  {
    scanf("%c",&a[i]); 
  }
}

测试a[i]!='*' 不是使用与此语句中使用的i 相同的值来执行的

  scanf("%c",&a[i]); 

在扫描和测试之间i 递增。

顺序是:

  1. i 设置为0
  2. 如果i 不再小于100,则退出循环
  3. 测试a[0]*
  4. 扫描到a[0]
  5. 递增i
  6. 如果i 不再小于100,则退出循环
  7. 测试a[1]*
  8. 扫描到a[1]
  9. 递增i
  10. 如果i 不再小于100,则退出循环
  11. 等等...

从上面您还了解到,代码测试a 的元素它们获得任何分配的值。这样做会引发臭名昭著的未定义行为,这是一件坏事,因为从这一刻起任何事情都可能发生。

【讨论】:

    【解决方案2】:

    问题在于for 语句运行i++ 增量之前 评估a[i] != '*' 循环退出条件。如果您在valgrind 下运行程序,这一点非常明显,这是一个跟踪未初始化内存的内存调试器:

    Enter the array
    ==3590== Conditional jump or move depends on uninitialised value(s)
    ==3590==    at 0x108606: main (t.c:10)
    ==3590== 
    *
    ==3590== Conditional jump or move depends on uninitialised value(s)
    ==3590==    at 0x10862C: main (t.c:10)
    ==3590== 
    

    (第一次未初始化的内存访问发生在读取任何字符之前,因为在第一次循环执行之前也检查了循环退出条件。)

    【讨论】:

    • 感谢您的评论。所以这意味着我们没有任何选项来检查这样的退出条件。只有第二个代码 sn-p 可以正常工作。正确吗?
    • 是的,在读取第一个字符之前,您无法检查这样的退出条件。
    【解决方案3】:

    这是因为循环在执行内部语句之前评估条件。

    所以,它是这样的:

    1. 我们有一个柜台
    2. 条件检查
    3. 已执行循环语句
    4. 计数器递增

    所以循环在你输入之前就已经检查了“*”。

    【讨论】:

    • OK.. 现在我已经像这样修改了代码,它现在可以工作了 for(i=0;c!='*';i++) { scanf("%c",&a[i ]); c=a[i]; }
    猜你喜欢
    • 2022-11-16
    • 1970-01-01
    • 2010-11-14
    • 2015-01-21
    • 1970-01-01
    • 2021-08-22
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多