如何将拆分的字符串保存在C结构中包含的字符数组中?

Posted

技术标签:

【中文标题】如何将拆分的字符串保存在C结构中包含的字符数组中?【英文标题】:How to save a splitted string in character array contained in structure in C? 【发布时间】:2021-04-18 08:40:29 【问题描述】:

正如标题中所说,我想将文本的每一部分保存在我的结构中包含的字符数组中,称为Identity,代码如下:

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

char strExample[]="Andrew;Smith;18;Wall Street;New York;10011;USA";

typedef struct  Identity
    char firstName[20];
    char lastName[20];
    char age[5];
    char street[64];
    char city[20];
    char postCode[8];
    char country[20];
Identity;

void textParse()

  char *ptr = strExample; 
  char *token;
  int i = 0;
  while ((token= strsep(&ptr,";")) != NULL)
  
    printf("%s\n",token);
  


int main(int argc, char **argv) 

    textParse();

    return 0;

拆分效果很好,但我不知道如何将每个标记保存在 Identity 结构中。我该怎么做?

【问题讨论】:

请更改措辞:您没有在 typedef 中保存字符串;您将它们保存在结构中包含的字符数组中。 typedef 只是用来命名孩子。你也不能在 type 中存储任何东西;您可以将内容存储在变量中。 进行长度检查以验证每个标记是否适合每个目标字符数组,然后将其存储在那里。 是的,我正在考虑做类似的事情,但是你如何用循环来做呢? 【参考方案1】:

只需定义一个Identity类型的变量,然后使用strncpy()将每个token复制到struct的相关字段中:

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

#define STRNCPY_STRUCT_EL(string_field, src) strncpy(string_field, src, sizeof(string_field) - 1 )

char strExample[]="Andrew;Smith;18;Wall Street;New York;10011;USA";

typedef struct  Identity
    char firstName[20];
    char lastName[20];
    char age[5];
    char street[64];
    char city[20];
    char postCode[8];
    char country[20];
Identity;

void textParse(Identity *id)

  char *ptr = strExample; 
  char *token;
  int i = 0;

  memset(id, 0, sizeof(*id));
  while ((token = strsep(&ptr,";")) != NULL)
  //while ((token = strtok(ptr,";")) != NULL) //I used this in my test
  
    // ptr = NULL; //I used this in my test, to fit strtok
    switch(i++)
    
        case 0:
            STRNCPY_STRUCT_EL(id->firstName, token);
            break;
        case 1:
            STRNCPY_STRUCT_EL(id->lastName, token);
            break;
        case 2:
            STRNCPY_STRUCT_EL(id->age, token);
            break;
        case 3:
            STRNCPY_STRUCT_EL(id->street, token);
            break;
        case 4:
            STRNCPY_STRUCT_EL(id->city, token);
            break;
        case 5:
            STRNCPY_STRUCT_EL(id->postCode, token);
            break;
        case 6:
            STRNCPY_STRUCT_EL(id->country, token);
            break;
        
  


int main(int argc, char **argv) 
    Identity id;

    textParse(&id);

    printf("Identity:\n%s %s, %s y.o.\nLives in %s, %s (%s - %s)\n",
           id.firstName, id.lastName, id.age, id.street, id.city, id.postCode, id.country);

    return 0;

基本上我检查了令牌的位置,然后将其复制到结构的相应位置。我使用了switch-case。不是很优雅,但很有效 我使用自动计算字段大小的宏复制了它。我想复制 size-1 字符,因为我想为字符串终止符 '\0' 留出空间 之所以有效,是因为我之前memseted 整个结构为 0,所以在strncpy 之后,字符串终止符肯定在哪里 我必须更改textParse() 签名才能接受指向Identity 的指针。在里面我跳过了健全性检查(例如对 NULL 指针的检查)。我建议将它们添加到您的最终实现中 此实现会截断比相应 Identity 字段更长的任何标记

输出:

Identity:
Andrew Smith, 18 y.o.
Lives in Wall Street, New York (10011 - USA)

【讨论】:

【参考方案2】:

如果你想循环处理它,你需要事先将成员数组的信息——它们的大小和偏移量——累积在一个数组中(数组最方便):

例子:

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

char strExample[]="Andrew;Smith;18;Wall Street;New York;10011;USA";

typedef struct  Identity
    char firstName[20];
    char lastName[20];
    char age[5];
    char street[64];
    char city[20];
    char postCode[8];
    char country[20];
Identity;

void textParse(Identity *Id)

  static size_t const sizes[7]=
      sizeof((Identity)0.firstName),
      sizeof((Identity)0.lastName),
      sizeof((Identity)0.age),
      sizeof((Identity)0.street),
      sizeof((Identity)0.city),
      sizeof((Identity)0.postCode),
      sizeof((Identity)0.country),
  ;
  static size_t const array_offsets[7]=
      offsetof(Identity,firstName),
      offsetof(Identity,lastName),
      offsetof(Identity,age),
      offsetof(Identity,street),
      offsetof(Identity,city),
      offsetof(Identity,postCode),
      offsetof(Identity,country),
  ;

  char *ptr = strExample;
  char *token;
  for (int i=0; (token= strsep(&ptr,";")) != NULL; i++)
  
      size_t const size = (size_t)(ptr-token);
      if(size > sizes[i]) return; /*doesn't fit*/
      else memcpy((char*)Id+array_offsets[i], token, size);
  


int main(int argc, char **argv) 

    Identity id; textParse(&id);
    puts("=============");
    puts(id.firstName);
    puts(id.lastName);
    puts(id.age);
    puts(id.street);
    puts(id.city);
    puts(id.postCode);
    puts(id.country);

    return 0;

【讨论】:

以上是关于如何将拆分的字符串保存在C结构中包含的字符数组中?的主要内容,如果未能解决你的问题,请参考以下文章

如何评估访问查询中另一个字段中包含的字段名称?

使用 .bat 文件在目录中包含的多个文件中查找和替换字符串

浏览哈希数组以删除Ruby中其他字符串中包含的字符串

在 useState 中保存的数组中包含的一系列对象中增加键的值 (+1)

如何在awk中将分隔字符串拆分为数组?

NSPredicate 按数组中包含的第一个字母过滤