【问题标题】:While Loop will not Execute in C虽然循环不会在 C 中执行
【发布时间】:2017-10-31 19:05:20
【问题描述】:

当我运行这个程序时,除了最后的while循环块之外,所有的东西都被执行了。我被要求输入“每行要打印的符号数”,然后程序结束。任何帮助将不胜感激。

#include <stdio.h>

int main(void) {
    int num_lines;
    printf("Enter a number of lines, greater than or equal to 7, to print :  ");
    scanf("%d", &num_lines);

    if (num_lines < 7) {
        while ( num_lines < 7 ) {
            printf("Enter the number of lines to print\nMust be greater than or equal to 7 :  ");
            scanf("%d", &num_lines);
        }
    }

    char symbol;
    printf("Choose a symbol/character to be displayed */&/+/0/x :  ");
    scanf("%s", &symbol);

    int num_symbols;
    printf("Enter the number of symbols to print per line :  ");
    scanf("%d", &num_symbols);

    if (num_symbols < 7 || num_symbols > 27) {
        num_symbols = 19;
    }

    while (num_lines > 0) {
        while (num_symbols > 0) {
            printf("%s", symbol);
            --num_symbols;
        }
        printf("\n");
        --num_lines;
    }
    return;
}

【问题讨论】:

  • 简单问题,is num_lines > 0?
  • 是的,num_lines 输入 8,符号输入 *,num_symbols 输入 10。
  • O/T - 不需要if (num_lines &lt; 7) { .. 如果这是真的while ( num_lines &lt; 7 ) { 的主体将执行,否则它不会
  • scanf("%s", &amp;symbol); --> scanf(" %c", &amp;symbol);... printf("%s", symbol); --> printf("%c", symbol);

标签: c loops pointers while-loop scanf


【解决方案1】:

在这段代码中sn-p

char symbol;
printf("Choose a symbol/character to be displayed */&/+/0/x :  ");
scanf("%s", &symbol);

使用了无效的格式说明符%s。而是使用格式说明符" %c"

char symbol;
printf("Choose a symbol/character to be displayed */&/+/0/x :  ");
scanf(" %c", &symbol);

也在这个 printf 调用中

       printf("%s", symbol);

你必须使用格式说明符%c

       printf("%c", symbol);

为了保证这些循环能够正常工作

   while (num_lines > 0) {
       while (num_symbols > 0) {
           printf("%s", symbol);
           --num_symbols;
       }
       printf("\n");
       --num_lines;
   }

您需要使用中间变量在外循环的迭代之间存储num_symbols 的值。例如

   while (num_lines > 0) {
       int n = num_symbols; 
       while (n > 0) {
           printf("%c", symbol);
           --n;
       }
       printf("\n");
       --num_lines;
   }

【讨论】:

    【解决方案2】:

    您的代码有一个非常严重的错误,

    char symbol;
    scanf("%s", &symbol);
    

    是未定义的行为,因为 "%s" 需要一个指向至少大小为 2 的 char 数组的指针。在您的情况下,您正在传递一个指向单个 char 的指针,此类代码的效果是未定义的。

    相反,它可能是(至少

    char symbol[2];
    scanf("%1s", symbol);
    

    或者,看@BLUEPIXY的建议。

    在调用未定义的行为后,程序的内存可能会损坏,因此程序的其余部分可能由于多种原因而失败。

    您也永远不要检查scanf("%d", ...) 是否成功,这可能是导致未定义行为的另一个原因。

    始终检查 scanf() 是否返回正确的值。

    【讨论】:

      【解决方案3】:

      让我们将问题归结为它的核心:您正在覆盖call stack 上的 num_lines,因为您在真正想要一个字符时要求读取一个字符串。当 scanf 创建字符串时,它将以 null 终止......因此在堆栈上的单个字符之后添加一个 null character 。在 C 中使用指针的乐趣之一。

      (这不是堆栈溢出,而只是堆栈覆盖。)

      这是一个最小的失败示例。只需将 %s 更改为 %c 即可,一切正常:

      #include <stdio.h>
      int main(void) {
        int num_lines;
        sscanf("7", "%d", &num_lines);
        printf("at first, num_lines is %d\n", num_lines);
        char symbol;
        sscanf("x", "%s", &symbol);
        printf("but now, num_lines has become %d\n", num_lines);
        printf("value changed because the second sscanf overwrote\n");
        printf("      num_lines on the call stack!!!\n");
        return; 
      }
      

      你会注意到我很懒;在测试期间使用sscanf 可以减少烦人的打字操作。

      运行它,你会得到:

      $ gcc scan.c ; ./a.out
      at first, num_lines is 7
      but now, num_lines has become 0
      value changed because the second sscanf overwrote
            num_lines on the call stack!!!
      

      【讨论】:

        【解决方案4】:

        您的问题在于 char 变量 symbol。您将 symbol 声明为字符变量并将其作为字符串读取。还有一个问题。当您使用scanf 同时读取字符串或字符和数字时,请始终在读取数值之前读取字符串或字符值。原因是scanf 还读了一个字符\n,这总是会产生问题。

        现在更改您的代码,如下所示:-

        #include <stdio.h>
        
        int main(void) {
            int num_lines;
            char symbol;
            printf("Choose a symbol/character to be displayed */&/+/0/x :  ");
            scanf("%c", &symbol);
            printf("Enter a number of lines, greater than or equal to 7, to print :  ");
            scanf("%d", &num_lines);
        
        if (num_lines < 7) {
            while ( num_lines < 7 ) {
                printf("Enter the number of lines to print\nMust be greater than or equal to 7 :  ");
                scanf("%d", &num_lines);
            }
        }   
        
        int num_symbols;
        printf("Enter the number of symbols to print per line :  ");
        scanf("%d", &num_symbols);
        
        if (num_symbols < 7 || num_symbols > 27) {
            num_symbols = 19;
        }
        
        while (num_lines > 0) {
            while (num_symbols > 0) {
                printf("%s", symbol);
                --num_symbols;
            }
            printf("\n");
            --num_lines;
         }
          return 0;//you have to return a value
        }
        

        如果仍然给您任何问题,只需硬编码symbol = '*'; 并尝试。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-09-14
          • 1970-01-01
          • 2017-03-16
          • 2013-03-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多