0

私は現在のCコードを持っています:

#include <string.h> // strdup
#include <stdio.h> // printf
#include <stdlib.h> // free

int main(int argc, char *argv[])
{
  const char isostr[] = "\\ISO 2022 IR 13\\ISO 2022 IR 87";

  char *query = strdup( isostr );
  char *token;
  char *str1;
  char *saveptr1;
  const char delim[] = "\\";

  for (str1 = query; ; str1 = NULL)
    {
    token = strtok_r(str1, delim, &saveptr1);
    if (token == NULL)
      break;
    printf(" --> %s\n", token);
    }
  free( query );

  return 0;
}

ただし、返されます:

 --> ISO 2022 IR 13
 --> ISO 2022 IR 87

戻る必要がありますが:

 --> [null/empty]
 --> ISO 2022 IR 13
 --> ISO 2022 IR 87

strtok_r は、文字列 "AA\BB\CC" と "AA\BB\CC\" または "\AA\BB\\CC" の間に違いはないようです。

4

3 に答える 3

2

区切り文字が 1 文字のみの場合は、トークン化する代わりに strchr を使用して検索できます。strtok は、すべての区切り文字を区切り文字として使用します。

str1 = query;
while (1)
{
    char * sep = strchr(str1, '\\')
    if (sep != NULL) *sep = 0;
    printf(" --> %s\n", str1);
    if (sep == NULL) break;
    str1 = sep + 1;
}
于 2013-09-16T14:27:44.193 に答える
1

区切り文字が常に 1 文字の場合は、次のようにできます。

char isostr[] = "\\ISO 2022 IR 13\\ISO 2022 IR 87";
char *p = isostr;
for (;;) {
    char *next = strchr(p, '\\');
    int len = next ? next-p : strlen(p);
    // This code makes a copy and frees it right away.
    // You may prefer your approach of `strdup`-ing, and setting '\0' in place.
    char *s = malloc(len+1);
    memcpy(s, p, len);
    s[len] = '\0';
    printf("--> '%s'\n", s);
    free(s);
    if (!next) break;
    p = next+1;
}

これにより、途中に空のトークンがある限り、先頭と末尾の空のトークンが処理されます。これはideoneのデモです。

于 2013-09-16T14:37:09.543 に答える
0

strtokその動作を持つ -like 関数を自分で簡単に実装できます。

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


/* \short tokenize a string
 * \param delim a delimiter char
 * \param str the string to tokenize or NULL for the next result
 * \return the current token or NULL if end of tokens.
 */
char* tokenize(char delim, char *str) {
    static char *stat_str = NULL;
    static char *position = NULL;
    static char *end;
    char *c;

    /* Add some assertions here... */

    if (str != NULL) {
        stat_str = str;
        end = stat_str + strlen(str) + 1;
    }
    position = stat_str;

    /* If the current position is the end of the original string, return NULL */
    if (position == end) {
        return NULL;
    }

    /* Search for the next occurence of the delimiter and change it to a null char */
    for (c = position; *c != 0; c++) {
        if (*c == delim) {
            *c = 0;
            break;
        }
    }

    /* Set the position to the next char */
    stat_str = c + 1;

    /* return the current token */
    return position;
}

int main() {
    const char str[] = "\\ISO 2022 IR 13\\ISO 2022 IR 87";

    char *query = strdup(str);

    for (char *token = tokenize('\\', query); token != NULL;token = tokenize('\\', NULL)) {
        printf("Token [%s]\n", token);
    }

    free(query);
}
于 2013-09-16T15:02:12.803 に答える