繁体   English   中英

如何正确打印 C 中结构类型数组的所有元素?

[英]How to correctly print all elements of an Array of type struct in C?

我有一个结构:

typedef enum
{
    Cat = 1,
    Dog,
    GuineaPig,
    Parrot,
} SPECIES;

#define MaxNameLength 25
#define MaxNrAnimals 20

typedef struct
{
    char    Name[MaxNameLength];
    SPECIES Species;
    int     Age;
} ANIMAL;

我尝试使用以下方法仅打印名称字符串:

ANIMAL animals[MaxNrAnimals];
for (int j = 0; j < sizeof(animals) / sizeof(animals[0]); j++) {
    printf("%c", animals[j].Name);
}

这将返回:

@dê¼╨⌠<`ä¿╠≡8\Çñ╚∞

无论是否填充了数组“动物”。 我将如何正确打印出阵列名称的每个现有成员?

%c格式说明符用于打印单个字符; 对于字符串,您应该使用%s格式。 此外,您可能需要考虑在每个名称后添加换行符。 以下更改将解决问题:

ANIMAL animals[MaxNrAnimals];
for (int j = 0; j < sizeof(animals) / sizeof(animals[0]); j++) {
//  printf("%c", animals[j].Name);
    printf("%s\n", animals[j].Name);
}

注意:为了使%s格式起作用,每个Name字段都应该是一个以nul结尾的字符串

ANIMAL animals[MaxNrAnimals];
for (int j = 0; j <MaxNrAnimals ; j++) {
printf("%s\n", animals[j].Name);
     }

尝试这个

其他答案在解决您的问题时非常正确。 我想添加一些背景故事。

C 字符串是包含字符值的字节 memory 中的连续序列的地址 - 即char* 您的 output 包含奇怪字符的原因是因为您告诉printf将指向动物名称的 memory 地址视为单个字符。

如果我们这样写代码,

#include <stdio.h>

int main() {
  char *str = "blah blah blah";
  printf("%c\n", str);
}

一个理智的编译会警告你你是。 将您的地址强制转换为不适当的类型:

$ gcc -o ct t.c
t.c:5:18: warning: format specifies type 'int' but the argument has type
      'char *' [-Wformat]
  printf("%c\n", str);
          ~~     ^~~
          %s
1 warning generated.

您应该预料到您编写的任何会在编译时引发警告的代码都会出现问题。 代码可能仍会完成编译,但这并不意味着它会正常工作。 立即修复所有编译器警告 - C 是一种棘手的语言,如果您忽略编译器警告,您可能会出现意外行为,很可能出现在看似不相关的代码部分。

就我而言,我最终得到了这样的结果,因为字符串地址的第一个字节不是有效的可打印字符序列:

$ ./ct
�

检查十六进制的 output 有助于我们看到\n (我的环境中的 ascii 值0a ,又名“换行符”,又名 ascii 中的“换行符”)。 立即进行的是 '%c' output - 0xa2值的十六进制值。 由于这不在标准的 7 位 ascii 表中,并且我的终端设置为 unicode,因此该字符无效且不可打印,因此显示了 字符。

$ ./ct | hexdump
0000000 a2 0a
0000002

如果我们将%c更改为%s ,我们将不再收到编译器警告,并且代码可以正常工作。

$ cat t.c
#include <stdio.h>

int main() {
  char *str = "blah blah blah";
  printf("%s\n", str);
}

$ gcc -o ct t.c
[ no output ]

$ ./ct
blah blah blah

$ ./ct | hexdump
0000000 62 6c 61 68 20 62 6c 61 68 20 62 6c 61 68 0a
000000f

我包含了 hexdump,以防您想查看我的字符串blah blah blah\n是如何按字节显示的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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