简体   繁体   English

While循环不会在C中执行

[英]While Loop will not Execute in C

When I run this program, everything is executed except for the block of while loops at the end. 当我运行该程序时,除了while循环块的末尾之外,其他所有内容都将执行。 I am asked for the "number of symbols to print per line" and then the program ends. 我被问到“每行要打印的符号数”,然后程序结束。 Any help would be greatly appreciated. 任何帮助将不胜感激。

#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;
}

Your code has a very severe bug, 您的代码有一个非常严重的错误,

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

is undefined behavior, because "%s" expects a pointer to a char array of at least size 2. In your case, you are passing a pointer to a single char , the effects of such code is undefined. 是未定义的行为,因为"%s"期望指向至少大小为2的char数组的指针。在您的情况下,您正在将指针传递给单个char ,此类代码的作用是不确定的。

Instead, it could be ( at least ) 相反,它可能是( 至少

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

Or, see @ BLUEPIXY 's suggestion. 或者,请参阅@ BLUEPIXY的建议。

After invoking undefined behavior , the program's memory could become corrupted so the rest of the program could fail for multiple reasons. 调用未定义的行为后 ,程序的内存可能会损坏,因此程序的其余部分可能由于多种原因而失败。

You also, never check that scanf("%d", ...) was succesful potentially another cause for undefined behavior . 您也不要检查scanf("%d", ...)是否成功可能是导致未定义行为的另一原因。

ALWAYS check that scanf() returns the right value. 始终检查scanf()返回正确的值。

In this code snippet 在此代码段中

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

there is used invalid format specifier %s . 使用了无效的格式说明符%s Instead use format specifier " %c" 而是使用格式说明符" %c"

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

Also in this call of printf 同样在printf的调用中

       printf("%s", symbol);

you have to use the format specifier %c 您必须使用格式说明符%c

       printf("%c", symbol);

To provide that these loops would work correctly 提供这些循环将正常工作

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

you need to use an intermediate variable to store the value of num_symbols between iterations of the outer loop. 您需要使用一个中间变量来存储外循环迭代之间的num_symbols值。 For example 例如

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

Let's boil the problem down to it's core: you're overwriting num_lines on the call stack because you're asking to read a string when you really want a character. 让我们将问题归结为它的核心:您正在覆盖调用堆栈上的num_lines,因为您在真正想要一个字符时要求读取字符串。 When scanf creates the string, it will be null terminated ... and so add a null character after the single char on the stack. 当scanf创建字符串时,它将以null终止...,因此在堆栈上的单个char之后添加一个null字符 One of the joys of working with pointers in C. 在C语言中使用指针的乐趣之一。

(This isn't a stack overflow but rather just a stack overwrite.) (这不是堆栈溢出,而只是堆栈覆盖。)

Here is a minimal example of failure. 这是失败的最小示例。 Just change the %s to %c and everything will work: 只需将%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; 
}

You'll notice that I'm lazy; 您会发现我很懒。 use sscanf during testing to have less annoying typing to perform. 在测试过程中使用sscanf可以减少烦人的输入。

Run it and you get: 运行它,您会得到:

$ 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!!!

Your problem is with char variable symbol . 您的问题是char变量symbol You are declaring symbol as character variable and reading it as string. 您将symbol声明为字符变量,并将其读取为字符串。 There is one more issue. 还有一个问题。 While you are using scanf to read string or character and number at the same time always read the string or char value before reading a numeric value. 使用scanf同时读取字符串或字符和数字时,请始终在读取数字值之前读取字符串或char值。 The reason is scanf also read one more character \\n for which it always creates problem. 原因是scanf还会再读取一个字符\\n ,这总是会造成问题。

now change your code like below:- 现在更改您的代码,如下所示:-

#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
}

if still giving you any problem just hard coded symbol = '*'; 如果仍然给您带来任何问题,只需硬编码symbol = '*'; and try. 并尝试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM