在 C 中初始化固定的字符串数组并在运行时向其添加条目

问题描述 投票:0回答:1

我在 C 中声明了字符串数组,如下所示

    static struct userRolesUpdatePost
{
    char userName[32+1];
    char userGroups[16][32+1];
    unsigned int validtyTime;

}userRolePost;

我正在初始化上面的字符串数组,结构如下

for(int i=0;i<16;i++) { strncpy(userRolePost.userGroups[i], "", 2); } // Initialize string array

我想在最后添加条目。在运行时在上面的数组末尾添加条目时,我正在做如下

for (int i = 0; i < 16; i++)
{
    if (strcmp(userRolePost.userGroups[i],  "") == 0)
    {
        printf("Adding new group %s, \n ", name);
        strncpy(userRolePost.userGroups[i], name, 32);
        return OK;
    }
    continue;
}

我认为我们可以做得比上面的更安全和可读。我们可以用 C 做更好的方法吗?

感谢您的时间和指导。

arrays c string char
1个回答
2
投票
  • 将类型定义与变量声明分开通常是一种很好的做法。所以我会重写结构为:

    typedef struct 
    {
        char userName[32+1];
        char userGroups[16][32+1];
        unsigned int validtyTime;
    } userRolesUpdatePost;
    
    static userRolesUpdatePost userRolePost;
    

    (或者,如果您在 Linux 粉丝俱乐部,则可以选择

    struct userRolesUpdatePost { ... };
    然后
    struct userRolesUpdatePost userRolePost;
    ,这也很好,只是不是我个人喜欢的风格。)

  • 当我们这样做时,利用 C 的默认初始化规则:

    static userRolesUpdatePost userRolePost = { 0 };
    
  • strncpy
    是一个危险的功能,几乎应该总是避免。此处没有用处,因为您提前知道长度并且传递的所有参数都经过清理。
    strcpy
    这样既安全又快捷,所以请改用它。见strcpy是否危险,应该用什么代替?了解
    strncpy
    的设计问题。

  • if (strcmp(userRolePost.userGroups[i],  "") == 0)
    是可以接受的,并且可能会得到很好的优化,但它实际上与
    if(userRolePost.userGroups[i][0] == '\0')
    是一样的,所以你不妨写一下。它不会使代码变慢,但可能会使代码变快。两种形式都具有足够的可读性,因此这只是速度的微优化。

  • 循环结束时的
  • continue;
    只是混乱。一般来说,避免使用
    continue
    /
    goto
    “意大利面条式编程”关键字。它们的存在几乎总是一个标志,表明应该以更好的方式重写循环。它们有一些有效的用途,但是它们太少而且介于两者之间,所以最好完全避免使用这两个关键字。

  • 避免使用“幻数”,例如 16 和 32。将它们替换为命名常量。


更快、更安全、更易读的清理程序可能如下所示:

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

#define USER_NAMES_N  32
#define USER_GROUPS_N 16

typedef struct 
{
    char userName [USER_NAMES_N+1];
    char userGroups [USER_GROUPS_N][USER_NAMES_N+1];
    unsigned int validtyTime;
} userRolesUpdatePost;

int main (void)
{
  static userRolesUpdatePost userRolePost = { 0 };

  for (size_t i = 0; i < USER_GROUPS_N; i++)
  {
    // name should be obtained  from somewhere here
    char name[]="something";

    if(userRolePost.userGroups[i][0] == '\0')
    {
      printf("Adding new group %s, \n ", name);
      strcpy(userRolePost.userGroups[i], name);
      return OK;
    }
  }
}

但是请注意,存储由

char*
指向的字符串(动态分配)可能是一个更明智的解决方案。它提供了更多的执行开销(以及常见的
malloc
问题的可能性)但它节省了大量空间,以防您需要分配这些结构的长数组。如果您愿意,它还可以消除 32 个字符的限制。

© www.soinside.com 2019 - 2024. All rights reserved.