【问题标题】:How do I print the contents of an array of strings?如何打印字符串数组的内容?
【发布时间】:2020-03-08 19:11:19
【问题描述】:

我已经使用以下字符串创建并初始化了一个数组:

char print_names[][10] = {"\t\t1. John\n",
                          "\t\t2. Smith\n",
                          "\t\t3. Jane\n",
                          "\t\t4. Mary\n",
                          "\t\t5. Lisa\n"};

据我所知,数组名本身就是一个指针。所以当我把这些行:

    printf("%c", *print_names[0]);
    printf("%c", *print_names[1]);

它应该指向那个数组元素的内容。但是控制台上什么也没有打印出来。

我进入调试器,它清楚地表明每个元素都包含适当的字符串。我不确定我在哪里做错了。

编辑:我还在学习有关数组和指针的基础知识,所以我没有在文件中包含<string.h>

附加问题:是否可以在不使用字符串的情况下打印内容(名称)?

好的。我想到了。我想我现在明白了。感谢您的回答。

【问题讨论】:

  • 1) *print_combos[0]type 是什么(它与 print_combos[0] 有何不同)? 2) "%c" 的用途是什么(它与 "%s" 有何不同以及各自期望的类型)?
  • 为字符串指定的格式是%s,而不是%c
  • 对不起,我回去将 print_combos 更改为 print_names。这是一个错字。
  • 变量叫什么并不重要 - 编辑后类型/范围/用法仍然相同。
  • 小心字符串,数组中的一个字符串(如您所展示的那样)将 not 以 null 结尾,因此将其视为以 null 结尾字符串(如以%s 格式打印)将导致未定义行为。最好将数组的大小从 10 增加到更大。

标签: c arrays string pointers


【解决方案1】:

*print_names[0] 等于 print_names[0][0]。它是print_names 中第一个字符串的第一个字符。

由于print_names 数组中每个字符串的第一个字符是一个制表符 ('\t'),因此您打印这个实际上不可见的制表符。

如果你想打印字符串本身,你需要使用%s 作为格式,并传递一个指向第一个字符的指针。可以这样做:

printf("%s", print_names[0]);

另一方面,如果您想要打印选项卡并使其可见,则用其他字符包围输出。喜欢

printf("tab = \"%c\"\n", print_names[0][0]);

这将打印用双引号括起来的选项卡。

【讨论】:

  • 前导标签将是“可见的”,因为它们将被渲染(显示?发射?)为 4/8 个空格,例如。在控制台或文本编辑器上。
  • @user2864740 但是你怎么看空格,除非你在它后面打印一些东西?
  • 所有字符串都有前导制表符,而不是尾随制表符。
  • @user2864740 是的,OP 正在打印第一个选项卡,没有其他内容。
  • 是的。这归结为根本问题:“它应该指向该数组元素的 [整个] 内容。”
【解决方案2】:

数组print_names有2个维度:

  • 元素的数量由初始化程序确定:在您的示例中为 5
  • 数组中每个元素中char元素的数量定义为10

问题是 5 个初始化器正好有 10 个字符,一个有 11 个字符。初始化器与对象定义不一致,且所有元素都不是以空字符结尾的字符串。

您应该将宽度至少更改为 12,并且可以使用 printf() 以这种方式打印数组元素:

#include <stdio.h>

void print_array() {
    char print_names[][12] = {
        "\t\t1. John\n",
        "\t\t2. Smith\n",
        "\t\t3. Jane\n",
        "\t\t4. Mary\n",
        "\t\t5. Lisa\n"
    };
    size_t count = sizeof(print_names) / sizeof(print_names[0]);
    for (size_t i = 0; i < count; i++) {
        printf("%s", print_names[i]);
    }
}

关于你的方法:

据我所知,数组名本身就是一个指针。

不是真的:数组的名称就是这样。当您在 sizeof(n) 以外的表达式中使用数组名称时,它衰减为指向数组第一个元素的指针。

下面的行输出第一个和第二个字符串的第一个字节:

printf("%c", *print_names[0]);  // same as print_names[0][0]
printf("%c", *print_names[1]);  // same as print_names[1][0]

【讨论】:

  • 谢谢,我忘记了转义序列!您能否详细说明为什么使用 size_t 和 sizeof?您是否针对直接分配的内存(即更精确)而不是仅使用常量 5?
  • @karln-create:您可以通过将数组sizeof(a) 的字节大小除以元素sizeof(a[0]) 的大小来计算数组a 的元素数。这适用于任何数组,但 a 必须是实际数组,而不是指针或函数参数。
  • 谢谢,这是有道理的。我忘记了在声明数组大小时我可以直接进行数学运算。我是初学者,所以我需要一点点了解所有的小部分。
【解决方案3】:

由于您对数组进行了超尺寸处理(有 10 个条目,但您只填充了 5 个,其他条目填充了 NULL 指针),您可以使用以下命令打印数组内容(每行一个字符串):

char **p;
for (p = print_names; *p; p++)
    printf("%s", *p);

相当于这段代码:

int i;
for (i = 0; print_names[i]; i++)
    printf("%s", print_names[i]);

如果你知道数组中有 5 个元素:

int i;
for (i = 0; i < 5; i++)
    printf("%s", print_names[i]);

【讨论】:

    【解决方案4】:

    它有效,但是因为每行的第一个元素是 \t 你不会看到任何你也可以使用的东西

    printf("%s", print_names[0])

    打印:\t\t1。约翰\n
    这一行。

    请注意,您在数组的第二维中放置了超过 10 个字符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-10
      • 1970-01-01
      • 2021-09-21
      相关资源
      最近更新 更多