【问题标题】:Find out string array lengthand each string length找出字符串数组长度和每个字符串长度
【发布时间】:2017-11-17 08:02:08
【问题描述】:

考虑以下 C 语言中的“字符串”数组:

const char* const animals[] =
{
    "",
    "Cat",
    "Dawg",
    "Elephant",
    "Tiger",
};

是否可以获得:

  1. animals 数组中元素(字符指针)的数量?

  2. 每个数组成员的长度,即。元素 0 的 size = 1,元素 1 的 size = 4 等等?

我当然尝试使用sizeof,但它似乎没有返回任何有意义的东西。我认为预编译器应该可以计算出数组中元素的数量以及每个元素的大小。对于后者,也可以搜索\0 字符并定义长度。但是我想知道为什么在使用sizeof 时无法获得正确的数组大小(即animals 数组中的元素数)?

感谢所有建议。

编辑:

  1. 是的,我指的是预处理器,而不是预编译器,抱歉。

  2. 为什么我需要这个功能? 我正在解析来自串行端口的传入字符串。我需要弄清楚接收到的字符串是否与我的预配置表中的任何字符串匹配。如果是这样,我需要该项目的索引。我需要快速的搜索算法。因此,我首先要检查字符串大小和之后的所有字节,前提是大小匹配。因此,我认为每个字符串的长度可能在编译时是已知的。

这是我目前的检查功能:

static int32_t  getStringIndex(const uint8_t* const buf, const uint32_t len)
{
    if (!len)
        return -1;

    int32_t arraySize = sizeof(animals) /  sizeof(animals[0]);
    uint32_t elementSize;

    // The algorithm 1st checks if the length matches. If yes, it compares the strings.
    for (int32_t i = 0; i < arraySize; i++)
    {
        elementSize = strlen(animals[i]);

        if (elementSize == len)
        {
            if (0 == memcmp(animals[i], buf, len))
            {
                return i;
            }
        }
    }

    return -1;
}

我不使用strcmp,因为buf 最后没有\0

【问题讨论】:

  • 您可以使用sizeof(animals)/sizeof(*animals) 来获取动物的数量(包括您可能不应该拥有的最初的“空”动物)。您可以使用strlen(animals[i]) 获取各个动物名称的长度。
  • 没有预编译器之类的东西。如果您的意思是预处理器,那么答案是否定的。预处理器只进行文本替换,它对变量的大小一无所知。也许你应该告诉我们为什么你需要知道这一点。你的用例是什么?
  • 我已经编辑了我的问题。
  • 您可以在程序初始化期间一劳永逸地计算animals 中字符串的长度,因此您无需一遍又一遍地调用strlen。我认为您无法获得数组中字符串文字的长度(例如,sizeof(animals[2]) 不是字符串的长度,而是指针的大小)。
  • 其实这是个好主意。

标签: c arrays pointers char size


【解决方案1】:
  1. sizeof animals / sizeof *animals(以字节为单位的总大小除以单个元素的大小)

  2. strlen(animals[0]) + 1(字符串长度包括0终止符)

【讨论】:

  • 有没有办法知道预编译器中每个元素的大小?
  • @Bremen sizeof 提供编译时常量,除非用于可变长度数组。
  • 这就是为什么我想知道预编译器知道每个成员自 const 以来的时间有多长?
  • @Bremen 我不确定您所说的“预编译器”是什么意思。如果你的意思是预处理器,不,但你可以在宏的扩展中使用sizeof。 (如果您有更多问题,请编辑您的问题(如果它非常相关)——或者提出一个新问题)
  • 是的,我的意思是预处理器,抱歉。谢谢。
【解决方案2】:
sizeof animals / sizeof animals[0]

返回数组中的元素个数。

您也可以使用strlen() 来获取数组中每个元素的长度。

来自标准 §7.24.6.3

strlen 函数返回前面的字符数 终止空字符。

sizeof 也是一个运算符。

来自标准 §6.5.3.4

sizeof 运算符的另一个用途是计算 array 中的元素:

     sizeof array / sizeof array[0]

【讨论】:

    【解决方案3】:

    您可以使用预处理器来构建一个结构数组,其中包含长度和指向字符串的指针,如下所示:

    #include <stdio.h>
    
    struct animalentry
    {
      int size;
      const char* const name;
    };
    
    #define ANIMAL_ENTRY(a) { sizeof a - 1, a },
    
    const struct animalentry animals[] =
    {
      ANIMAL_ENTRY("")
      ANIMAL_ENTRY("Cat")
      ANIMAL_ENTRY("Dawg")
      ANIMAL_ENTRY("Tiger")
    };
    
    int main()
    {
      for (int i = 0; i < sizeof animals / sizeof animals[0]; i++)
      {
        printf("Name = %s, length = %d\n", animals[i].name, animals[i].size);
      }  
    }
    

    输出将是:

    Name = , length = 0
    Name = Cat, length = 3
    Name = Dawg, length = 4
    Name = Tiger, length = 5
    

    这应该很容易适应您的getStringIndex 函数。

    【讨论】:

    • 在您的情况下,由于nameconst char* 而不是const char* const,它不会存储在RAM 中而不是FLASH 中吗?
    • @Bremen 我不知道,这是特定于您的平台的,但您当然可以根据您的需要调整它并添加第二个 const
    • 是的,这绝对是最容易实施的解决方案。已经实施和工作。谢谢。
    猜你喜欢
    • 2017-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 2021-05-26
    • 1970-01-01
    • 2018-01-20
    相关资源
    最近更新 更多