简体   繁体   中英

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. 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.

Instead, it could be ( at least )

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

Or, see @ BLUEPIXY 's suggestion.

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 .

ALWAYS check that scanf() returns the right value.

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 . Instead use format specifier " %c"

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

Also in this call of printf

       printf("%s", symbol);

you have to use the format specifier %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. 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. When scanf creates the string, it will be null terminated ... and so add a null character after the single char on the stack. One of the joys of working with pointers in 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:

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

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 . You are declaring symbol as character variable and reading it as string. 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. The reason is scanf also read one more character \\n for which it always creates problem.

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 = '*'; and try.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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