虽然循环不会在C

时间:2017-10-31 19:05:21

标签: c loops pointers while-loop scanf

当我运行这个程序时,除了最后的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;
}

4 个答案:

答案 0 :(得分:3)

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

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

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

相反,它可能是(至少

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

或者,请参阅@ BLUEPIXY的建议。

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

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

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

答案 1 :(得分:3)

在此代码段中

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 :(得分:0)

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

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

这是失败的最小例子。只需将Notice on line 429 in file /home/onywf3fr9a/public_html/app/cache/dev/classes.php 更改为%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

答案 3 :(得分:0)

你的问题是char变量symbol。您将symbol声明为字符变量并将其作为字符串读取。还有一个问题。当您使用scanf同时读取字符串或字符和数字时,请始终在读取数字值之前读取字符串或char值。原因是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 = '*';并尝试。