使用带有tolower()或toupper()的putchar()打印A-Z会在第一个char处停止循环

时间:2018-04-22 03:13:08

标签: c

尝试迭代ASCII字符

我想以小写字母打印所有 A-Z 字符,但我只打印了第一个字符。

#include <stdio.h>

int main()
{
    for(int x = 'A'; x <= 'Z'; x++)
    {
        x = tolower(x);
        putchar(x);
    }
    return 0;
}

输出

a

3 个答案:

答案 0 :(得分:3)

您的方法存在的问题是您正在修改变量 用作循环的运行变量。

看看ASCII Table,您会注意到大写字母 字母的整数值小于小写字母。

所以在第一次迭代中,x被分配给A,然后你做

x = tolower(x);

x的值从A更改为aa的整数值是97, 它大于Z的整数值(即90)。当下一个 迭代开始x++被执行,这使得x甚至大于90,所以条件

x <= 'Z'

将被评估为false,因此循环停止。

所以,不要改变你正在使用的变量作为运行变量 环。你可以做任何一件事

for(int x = 'A'; x <= 'Z'; x++)
{
    int lower_x = tolower(x);
    putchar(lower_x);
}

for(int x = 'A'; x <= 'Z'; x++)
{
    putchar(tolower(x));
}

在这两种情况下,x仅由循环本身修改,您不会遇到 你遇到的问题。

请注意,

int main()
{
    for(int x = 'A'; x <= 'z'; x++) // Notice (x <= 'Z') > > (x <= 'z')
    {
        x = tolower(x);
        putchar(x);
    }
    return 0;
}
在这种情况下,

给出了相同的结果,这一般不正确 解决方案,因为它仍在修改x变量之外的变量 环结构。 x的值 将是

  • 第一次迭代 x == 'A'
  • 第二次迭代 x == 'b'
  • 第三次迭代 x == 'c'
  • ...

就像我说的那样,最终结果可能是一样的,但这只是巧合。图片 你有这个任务:打印值乘以100从10到20

如果你这样做

for(int x = 10; x <= 20; x++)
{
    x = x * 100;
    printf("%d\n", x);
}

您将拥有与以前相同的情况。但解决方案

for(int x = 10; x <= 200; x++)
{
    x = x * 100;
    printf("%d\n", x);
}

会打印完全不正确的值。喜欢你的问题,正确的 解决方案是不在块中修改 x

for(int x = 10; x <= 20; x++)
{
    printf("%d\n", x * 100);
}

答案 1 :(得分:2)

int x = 'A'
ASCII中的

x 相当于 65

x <= 'Z'

我们知道x = 65.好吧,'Z'相当于90

第一次迭代:

条件表达式x <= 'Z'65 <= 90相同?的即可。

该行

x = tolower(x);
  

'A'(65)​​向'a'分配 x ,其值为(97)。

因此,在打印第一个字符后,循环将 x 增加1,然后再次迭代并询问相同的问题。

第二次迭代:

x <= 'Z' == 98 <= 90?嗯,这是错误 因此,循环将停止并使用0

退出主函数

要解决此问题,您需要询问 x 是否在小写字母范围内,是否为大写字母。
为什么?因为我们在第一次次迭代中说过, x 不再是大写字母。

<强>最终

#include <stdio.h>

int main()
{
    for(int x = 'A'; x <= 'z'; x++) // Notice (x <= 'Z') > > (x <= 'z')
    {
        x = tolower(x);
        putchar(x);
    }
    return 0;
}

或者我们根本不能改变 x

#include <stdio.h>

int main()
{
    for(int x = 'A'; x <= 'Z'; x++) // jumps from 'A'(65) to 'B'(66) to ... in order.
    {
        putchar(tolower(x)); // the return value is returned as a parameter
    }
    return 0;
}

返回值作为参数返回到函数tolower(),而不是将其分配给 x ,现在变量 x 不会弄乱我们的循环,我们可以保持我们应有的条件 x 现在每次迭代只增加1(x++;),然后它给函数赋予新值而没有任何ASCII顺序问题(不像第1次法)。

答案 2 :(得分:1)

请注意for循环

for(int x = 'A'; x <= 'Z'; x++)
{
    x = tolower(x);
    putchar(x);
}

只是while循环的语法糖 - 这里相当于

{
    int x = 'A';
    while (x <= 'Z') {
        x = tolower(x);
        putchar(x);
        x ++;
    }
}

当它到达x ++时,值为'a',即97,并且在增量之后,它将是'b',即98.自'b' <= 'Z'(98 &lt; = 90)为false,迭代停止。

C的许多新人认为for是一些神奇的结构,就像在其他一些编程语言中一样,这就是他们出错的地方。

P.S。如果你写了putchar(tolower(x));你的程序会有效。