【问题标题】:Problems with pointers to char array [duplicate]指向char数组的指针问题[重复]
【发布时间】:2018-04-10 03:40:25
【问题描述】:

这个程序应该遍历一个由 0 和 1 组成的数组,并计算有多少个 0、1 和所有组合在一起的字符。 但是,循环内的 print 语句会打印出一堆“48”和“49”。 即使正确计算了字符数,它似乎也不是从“if 语句”中的指针中提取值,而是获取内存地址。

代码本身:

#include <stdio.h>      /* using printf, gets, BUFSIZ */

int main(int argc, char *argv[])
{
    char input[BUFSIZ];

    int n;
    char *labelPtr;
    int zeroCount=0;
    int oneCount=0;
    n=0;

    gets(input);

    while(input[n])
    {
        labelPtr=&input[n];
        printf("%d \n", *labelPtr);
        if (*labelPtr==0)
        {
            zeroCount++;
        }
        if(*labelPtr==1)
        {
            oneCount++;
        }
        n++;
    }
    printf("The number of characters is %d \n", n);
    printf("The number of zeros is %d \n", zeroCount);
    printf("The number of ones is %d \n", oneCount);
}

【问题讨论】:

  • 在本世纪没有充分的理由使用gets。这是一个损坏的功能。
  • asciitable.com -- 一切都会变得清晰......(例如,十进制 48 是 ASCII '0' - 或 - ASCII '0' 是十进制 48 - 选择),为'1'...加1(提示:你printf ("%c", ...)putchar()打印一个字符,你使用"%d"输出一个“十进制”。)
  • 你需要用火烧掉你现在的 C 书/老师,换一本现代的。
  • 谢谢你们,帮了大忙。这实际上是我第一次用 C 编程。我知道这个问题的某些方面已经过时了,但我认为这是我的教授故意这样做的,目的是让我们了解指针和字符在 C 中是如何工作的。谢谢非常感谢所有帮助过的人!

标签: c pointers char


【解决方案1】:
  1. 不要使用gets。这是众所周知的安全问题原因。请改用fgets

  2. 您没有理由为labelPtr 使用char* 类型。只使用char label;

  3. if (*labelPtr == 0) 的使用不正确,因为 *labelPtrchar 并且字符 '0' 的值不等于整数常量 0。您需要将其与'0' 进行比较。 if (*labelPtr == '0')。同样,使用if (*labelPtr == '1')

  4. 要打印char,请使用格式说明符%c,而不是%d

    printf("%c \n", *labelPtr);
    

    如果您使用%d 作为格式说明符,您将获得用于将字符编码为输出的整数值。对于 ASCII 编码,48 对应字符 '0'49 对应字符 '1'


这是您发布的代码的更新版本。

#include <stdio.h>      /* using printf, gets, BUFSIZ */

int main(int argc, char *argv[])
{
    char input[BUFSIZ] = {};

    int n = 0;
    char label;
    int zeroCount=0;
    int oneCount=0;

    fgets(input, sizeof(input), stdin);

    while( input[n] )
    {
        label = input[n];
        printf("%c \n", label);
        if (label == '0')
        {
            zeroCount++;
        }
        if(label == '1')
        {
            oneCount++;
        }
        n++;
    }
    printf("The number of characters is %d \n", n);
    printf("The number of zeros is %d \n", zeroCount);
    printf("The number of ones is %d \n", oneCount);
}

【讨论】:

    【解决方案2】:

    您将阅读数字与阅读字符混淆了。当您使用fgets(或任何其他功能)阅读时,您会阅读字符。您读取的字符是由数值 0-127 表示的 ASCII 字符(大多数情况下,支持宽字符)。请参阅ASCII Table 前 31 个字符(ASCII 值 0-30)是您的控制字符和空白字符(例如 nul-charactertabnewline、...)127(del)同样是非-打印字符。其余的31-126组成可打印字符(包括可打印字符0-9

    注意:你从不使用gets,它很容易被利用和缓冲区溢出,它已从 C11 库中删除)

    不要将数字 0 与 ASCII 字符 '0' 混淆或等同(注意单引号)。

    在您尝试打印每个字符时的代码中,例如

        printf("%d \n", *labelPtr);
    

    您正在打印 ASCII 字符的 ASCII 值(十进制值)。您正在寻找'0''1' 并得到4849。这是因为字符 '0' 的 ASCII 码是 48'1' 的 ASCII 码是 49。如果你想打印字符,你需要:

        printf("%c\n", *labelPtr);
    

    此外,您的计数将永远不会记录任何内容。为什么?您正在测试 01 而不是 '0''1'。 (并注意 0nul-character - 因此在测试为真之前,您将超出字符串中的最后一个字符)。相反,您需要:

            if (*labelPtr == '0')
                zeroCount++;
            if(*labelPtr == '1')
                oneCount++;
    

    将它放在一起并清理不需要/未使用的变量,您可以执行以下操作:

    #include <stdio.h>      /* using printf, gets, BUFSIZ */
    
    int main (void)
    {
        char input[BUFSIZ] = "",
            *labelPtr = input;
        int n = 0,
            zeroCount=0,
            oneCount=0;
    
        fgets (input, BUFSIZ, stdin);
    
        for (; *labelPtr; labelPtr++, n++)
        {
            printf ("read ASCII char '%c' (%3d - decimal)\n", 
                    *labelPtr, *labelPtr);
            if (*labelPtr == '0')
                zeroCount++;
            if(*labelPtr == '1')
                oneCount++;
        }
        printf("characters: %d\nzeros     : %d \nones      : %d \n", 
                n, zeroCount, oneCount);
    }
    

    使用/输出示例

    $ echo "my 10 dogs have 100 fleas" | ./bin/zeroonect
    read ASCII char 'm' (109 - decimal)
    read ASCII char 'y' (121 - decimal)
    read ASCII char ' ' ( 32 - decimal)
    read ASCII char '1' ( 49 - decimal)
    read ASCII char '0' ( 48 - decimal)
    read ASCII char ' ' ( 32 - decimal)
    read ASCII char 'd' (100 - decimal)
    read ASCII char 'o' (111 - decimal)
    read ASCII char 'g' (103 - decimal)
    read ASCII char 's' (115 - decimal)
    read ASCII char ' ' ( 32 - decimal)
    read ASCII char 'h' (104 - decimal)
    read ASCII char 'a' ( 97 - decimal)
    read ASCII char 'v' (118 - decimal)
    read ASCII char 'e' (101 - decimal)
    read ASCII char ' ' ( 32 - decimal)
    read ASCII char '1' ( 49 - decimal)
    read ASCII char '0' ( 48 - decimal)
    read ASCII char '0' ( 48 - decimal)
    read ASCII char ' ' ( 32 - decimal)
    read ASCII char 'f' (102 - decimal)
    read ASCII char 'l' (108 - decimal)
    read ASCII char 'e' (101 - decimal)
    read ASCII char 'a' ( 97 - decimal)
    read ASCII char 's' (115 - decimal)
    read ASCII char '
    ' ( 10 - decimal)
    characters: 26
    zeros     : 3
    ones      : 2
    

    注意:下一行( 10 - decimal)的'和'是'\n'字符)

    查看一下,如果您还有其他问题,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-05
      • 2021-01-26
      • 2011-05-23
      • 2016-01-27
      • 2012-03-19
      • 1970-01-01
      • 1970-01-01
      • 2017-09-03
      相关资源
      最近更新 更多