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

cygmwpex  于 2023-03-01  发布在  其他
关注(0)|答案(1)|浏览(101)

我在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中做?
感谢您的时间和指导。

hc8w905p

hc8w905p1#

  • 将类型定义和变量声明分开通常是一种好的做法,因此我将把结构重写为:
typedef struct 
{
    char userName[32+1];
    char userGroups[16][32+1];
    unsigned int validtyTime;
} userRolesUpdatePost;

static userRolesUpdatePost userRolePost;

(Or如果您是Linux粉丝俱乐部的成员,可以选择struct userRolesUpdatePost { ... };,然后struct userRolesUpdatePost userRolePost;,这也可以,只是我个人不喜欢这种风格。)

  • 既然如此,就利用C的默认初始化规则:
static userRolesUpdatePost userRolePost = { 0 };
  • strncpy是一个危险的函数,几乎总是应该避免。这里没有使用它,因为你提前知道长度,并且所有传递的参数都经过了消毒。strcpy这样既安全又快速,所以改用它。请参见Is strcpy dangerous and what should be used instead?了解strncpy的设计问题。
  • if (strcmp(userRolePost.userGroups[i], "") == 0)是可以接受的,而且可能会得到很好的优化,但它实际上与if(userRolePost.userGroups[i][0] == '\0')是一样的,所以你最好这样写。它不会使代码变慢,但可能会使代码变快。这两种形式都有足够的可读性,所以这只是一个速度的微观优化。
  • 循环末尾的continue;只会让人感到混乱。一般来说,避免使用continue/goto“spaghetti programming”关键字。它们的出现几乎总是一个信号,表明循环应该以更好的方式重写。它们的使用是有效的,但它们很少,而且两者之间相距甚远,最好完全避免使用这两个关键字。
  • 避免使用“幻数”,如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个字符的限制。

相关问题