あなたのアプローチは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
にヘッダを読んでいたと仮定すると、今、あなたが興味を持っている各列の列インデックスと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));
}
}
}
の代わりにテーブルにオフセットを格納すると、もちろんswitch文にtarget
と同じようにポインタを格納することができます。しかし、それは直接&row.rssid
のようなものを指す必要があります。多分それはあなたのために十分です(私は既に十分以上のものを提供していると思います)。
しかし、私はこのオプションを指摘しますが、これは上記のようにmemcpy
を使用するより簡単かもしれません。そして、私が避けているものであるstrncpy
のものに巻き込まれます。
「char配列」または「文字列」は「char」ではなく「charを単語に分割する」という意味は、はっきりとは異なる意味を持ちます。 – spinkus