gpt4 book ai didi

c - 将字符拆分为 C 中的单词

转载 作者:可可西里 更新时间:2023-11-01 11:48:36 24 4
gpt4 key购买 nike

我正在将以下格式的行存储到一个字符中。每个单词由一个表格分隔。

BSSID              PWR  Beacons    #Data, #/s  CH  MB   ENC  CIPHER AUTH ESSID
00:34:34:34:34:34 -56 9 0 0 11 54e. WPA2 CCMP PSK wifi_id
00:44:44:44:44:34 -56 9 0 0 11 54e. WPA2 CCMP PSK wifi_id2
00:54:54:54:54:54 -56 9 0 0 11 54e. WPA2 CCMP PSK wifi_id3

我想拆分每一行(包含在一个字符中)以获得 BSSID、CH、CIPHER 和 ESSID 字段。我的最终目标是将每一行的字段存储在一个字符数组中,以便更舒适地使用它们。像这样:

char fields[] = { BSSID, CH,CIPHER, ESSID}

现在我正在使用strtok,以便拆分char 的\t,但这很不舒服。下面是我的第一种方法,但效果很差,因为它只关注第四行和第二行。有人可以帮我写代码吗?我也乐于接受一种不同的编程方式。

const char s[2]= "\t";
while (fgets(path, sizeof(path)-1, fp) != NULL) {
i = i + 1;
if (i == 4){
token = strtok(path, s);
/* walk through other tokens */
while( token != NULL )
{
token = strtok(NULL, s);
strncpy(field2, token, 18);
break;
}
}
}

最佳答案

您使用 strtok 的方法很好,但也许您想将数据存储到结构中。像下面这样的东西。我选择了固定的字符串最大长度,并且刚刚发明了它们可能是什么。

struct row_data {
char bssid[18];
char ch[4];
char cipher[10];
char essid[20];
};

如果您始终确切地知道列的顺序,您可以在这里停下来。只需使用枚举索引列:

enum column_id {
COL_RSSID = 0,
COL_CH = 5,
COL_CIPHER = 8,
COL_ESSID = 10
};

现在像这样的东西可以做到:

int column = 0;
char *target = NULL;
struct row_data row;
struct row_data empty_row = {0};

while( fgets(path, sizeof(path), fp) )
{
row = empty_row;

token = strtok(path, s);
for( column = 0; token; token = strtok(NULL,s), column++ )
{
switch( column )
{
case COL_RSSID: target = row.rssid; break;
case COL_CH: target = row.ch; break;
case COL_CIPHER: target = row.cipher; break;
case COL_ESSID: target = row.essid; break;
default: target = NULL;
}

if( target ) strcpy(target, token);
}

/* do something with row */
printf( "Read rssid=%s ch=%s cipher=%s essid=%s\n",
row.rssid, row.ch, row.cipher, row.essid );
}

同时制作 target_length 并没有太多额外的工作或类似的,可以用作 strncpy 的参数(我的例子很短,使用了 strcpy )。或者您可以换个方向,只在结构中存储指针。然后你可以使用动态分配来复制字符串。

现在,如果您的列顺序未知,则必须进一步抽象这一步。那将首先读取标题行并查找您感兴趣的部分,然后存储它们出现的列索引。这会使您的代码更加复杂,但并非没有道理。

起点可能是这样的(需要 <stdlib.h> ):

struct column_map {
const char * name;
size_t offset;
int index;
} columns = {
{ "RSSID", offsetof( struct row_data, rssid ), -1 },
{ "CH", offsetof( struct row_data, ch ), -1 },
{ "CIPHER", offsetof( struct row_data, cipher ), -1 },
{ "ESSID", offsetof( struct row_data, essid ), -1 },
{ NULL }
};

/* first read the header */
token = strtok(header, s);
for( column = 0; token; token = strtok(NULL,s), column++ )
{
for( struct column_map *map = columns; map->name; map++ ) {
if( map->index == -1 && 0 == strcmp(token, map->name) ) {
map->index = column;
}
}
}

你可以看到这是怎么回事。假设您已将 header 读入 header , 现在你已经填充了 columns使用您感兴趣的每一列的列索引。因此,在读取其他行时,您可以这样做而不是切换:

row = empty_row;
token = strtok(path, s);
for( column = 0; token; token = strtok(NULL,s), column++ )
{
for( struct column_map *map = columns; map->name; map++ ) {
if( map->index == column ) {
/* again, if using strncpy, store a length inside the map,
and use MIN(map->length, strlen(token)+1) or similar */
memcpy( (char*)&row + map->offset, token, strlen(token) );
}
}
}

除了在表中存储偏移量,您当然可以存储一个指针,就像我们对 target 所做的一样在开关语句中。但这需要直接指向类似 &row.rssid 的东西.也许这对你来说就足够了(我想我已经提供了足够多的东西)。

但公平地说,我会指出这个选项,它可能比使用 memcpy 更简单如上。我会加入 strncpy我一直在避免的事情。

struct row_data row;

struct column_map {
const char * name;
char *target;
size_t target_size;
int index;
} columns = {
{ "RSSID", row.rssid, sizeof(row.rssid), -1 },
{ "CH", row.ch, sizeof(row.ch), -1 },
{ "CIPHER", row.cipher, sizeof(row.cipher), -1 },
{ "ESSID", row.essid, sizeof(row.essid), -1 },
{ NULL }
};


/* ::: */


if( map->index == column ) {
strncpy( map->target, token, map->target_size );
map->target[map->target_size-1] = '\0'; /* in case of overflow */
}

关于c - 将字符拆分为 C 中的单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41056077/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com