【问题标题】:error on a char string with more than 15 characters超过 15 个字符的 char 字符串出错
【发布时间】:2021-02-03 04:39:41
【问题描述】:

为什么 gcc 不允许我使用 char 维度 >15?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char alphabet[]={'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
    int dim_alph;
    dim_alph=strlen(alphabet);
    printf("%s has %d characters\n", alphabet, dim_alph);
    return 0;
}`

它在字符串和维度上都给我无效的输出(如果我停在“P”字符而不是“O”字符)

【问题讨论】:

  • 您的 char 数组不是 c 字符串,缺少 nul 终止符。
  • 您需要添加 '\0' 作为字符。它是空终止符
  • 你应该使用char alphabet[] = "ABC...Z";
  • 除此之外,“维度”在这里是错误的词。数组的维度,无论其长度如何,都是1。
  • @KonradRudolph 好的,谢谢!

标签: c char printf undefined-behavior c-strings


【解决方案1】:

声明的数组

char alphabet[]={'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

不包含字符串,因为初始化器之间没有终止零。

所以strlen的电话

dim_alph=strlen(alphabet);

并在printf的调用中使用转换说明符%s

printf("%s has %d characters\n", alphabet, dim_alph);

调用未定义的行为。

你可以写

int dim_alph = ( int )sizeof( alphabet );
printf("%.*s has %d characters\n", dim_alph, alphabet, dim_alph);

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    char alphabet[] = 
    {
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 
        'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
    };

    int dim_alph = ( int )sizeof( alphabet );

    printf("%.*s has %d characters\n", dim_alph, alphabet, dim_alph);
    
    return 0;
}

程序输出是

ABCDEFGHIJKLMNOPQRSTUVWXYZ has 26 characters

另一种方法是使用字符串文字初始化数组。例如

#include <stdio.h>

int main(void) 
{
    char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    int dim_alph = ( int )( sizeof( alphabet ) - 1 );

    printf("%s has %d characters\n", alphabet, dim_alph);
    
    return 0;
}

程序输出又是

ABCDEFGHIJKLMNOPQRSTUVWXYZ has 26 characters

【讨论】:

    【解决方案2】:

    根据当前的初始化,数组alphabet 不是以空值结尾的,因此它不能用作字符串。尝试将其用作一个(例如:将其传递给需要字符串的函数),将导致超出分配的内存的越界访问(搜索空终止符),访问无效内存调用undefined behaviour

    如果你必须使用 if 作为字符串,你需要要么

    • 在大括号括起来的初始化列表中添加一个空终止符,如.....'X','Y','Z', '\0'};
    • 使用字符串字面量初始化数组,如char alphabet[]="ABCD....XYZ";

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-28
      • 1970-01-01
      • 1970-01-01
      • 2012-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多