7
votes

Besoin de savoir quand aucune donnée n'apparaît entre deux séparateurs de jeton à l'aide de Strtok ()

J'essaie de goverser une chaîne mais j'ai besoin de savoir exactement quand aucune donnée n'est vue entre deux jetons. par exemple, lors de la jouvre de la chaîne suivante " a, b, c , d, e code>" J'ai besoin de savoir sur les deux emplacements vides entre ' d code>' et ' E code> '... que je suis incapable de savoir simplement en utilisant strtok () code>. Ma tentative est présentée ci-dessous:

char arr_fields[num_of_fields];
char delim[]=",\n";
char *tok;
tok=strtok(line,delim);//line contains the data

for(i=0;i<num_of_fields;i++,tok=strtok(NULL,delim))
{
    if(tok)
        sprintf(arr_fields[i], "%s", tok);
    else
        sprintf(arr_fields[i], "%s", "-");          
}


3 commentaires

@DHAIVATPANDYA: Ce n'est pas un avis très utile à moins que cela soit accompagné d'une raison ...


Vous voulez dire "entre" C "et" D ""?


C'est des conseils extrêmement précis. Le problème est que strtok () est conçu pour ignorer les répétitions des caractères de séparateur de jeton et cela les oblitère. Par conséquent, si vous devez connaître des séparateurs de jetons adjacents ou si vous devez savoir quel séparateur a marqué la fin d'un jeton, vous ne pouvez pas utiliser strtok () pour le travail.


6 Réponses :


0
votes
  1. Parse (par exemple, strtok)
  2. trier
  3. insérer
  4. rincer et répéter au besoin :)

0 commentaires

2
votes

Vous ne pouvez pas utiliser strtok () si c'est ce que vous voulez. De la page man:

une séquence de deux caractères de délimitation ou plus contigus dans les analyses analysées La chaîne est considérée comme un seul délimiteur. Personniers de délimiteur à Le début ou la fin de la chaîne sont ignorés. Mettre un autre moyen: le Les jetons retournés par strtok () sont toujours des cordes non émises.

Par conséquent, il suffit de sauter de C à d dans votre exemple.

Vous allez avoir à analyser la chaîne manuellement ou peut-être de rechercher une bibliothèque d'analyse de la CSV qui faciliterait votre vie.


0 commentaires

0
votes

Vous pouvez essayer d'utiliser strchr pour trouver les emplacements des symboles , . TOKENISER manuellement votre chaîne jusqu'à la jeton que vous avez trouvée (en utilisant memcpy ou strncpy ), puis utilisez à nouveau Strchr. Vous serez en mesure de voir si deux ou plusieurs virgules sont à côté de l'autre de cette manière (Strchr retournera des chiffres que leur soustraction sera égale à 1) et vous pouvez écrire un si instruction pour gérer ce cas. < / p>


6 commentaires

Étant donné que les délimiteurs peuvent être des virgules ou une nouvelle ligne, strchr () n'est pas l'outil approprié à utiliser.


ne peut pas Strchr () localiser la valeur '\ n'?


Oui, strchr () peut trouver des virgules et trouver des nouvelles lignes, mais de trouver la prochaine "virgule ou nouvelle ligne", vous devez appeler strchr () deux fois, une fois que Rechercher la virgule, une fois pour la nouvelle ligne.


Vous ne pouvez pas utiliser une déclaration «cas»? Je pense que ce n'est pas l'outil le plus approprié à utiliser, mais cela peut résoudre le problème d'accord.


Il existe d'autres fonctions de chaîne - strgespn () , strcspn () , STRPBRK () en particulier - qui fait la majeure partie du travail nécessaire. Oui, je suis sûr que vous pourriez l'écrire à l'aide d'une déclaration , mais ce n'est pas ce qui vous dérange.


+1 Parce que vous avez raison :) J'ai toujours tendance à utiliser l'outil le plus simpliste et à construire à la main pour essayer de le faire fonctionner comme je le veux. Ceci, évidemment, me donne beaucoup de problèmes ...



16
votes

7.21.5.8 La fonction strokt

La norme indique ce qui suit concernant strtok :

[# 3] Le premier appel de la séquence recherche la chaîne pointé vers par s1 pour le premier caractère qui n'est pas contenue dans la chaîne de séparateur actuelle pointée par S2 . Si aucun caractère de ce type n'est trouvé, il n'y a pas de jetons dans La chaîne pointée par S1 et la fonction de fonction strutok un pointeur nul. Si un tel caractère est trouvé, c'est le début du premier jeton.

Dans la citation ci-dessus, nous pouvons lire que vous ne pouvez pas utiliser strtok comme solution à votre problème spécifique, car il traitera des caractères séquentiels trouvés dans Delims En tant que SIMPLE SIMPLE Jeton


Suis-je condamné à pleurer en silence, ou quelqu'un peut-il m'aider?

Vous pouvez facilement mettre en œuvre votre propre Version de strtok qui fait ce que vous voulez, voir les extraits à la fin de ce message.

strtok_single utilise STRPBRK (Char const * src, const char * delims) qui retournera un pointeur à la première occurrence de tout caractère dans Delims qui se trouve dans la chaîne NULL terminée src .

si aucun caractère de correspondance n'est trouvé que la fonction renvoie null.


xxx

Utilisation de l'échantillon xxx

sortie xxx


7 commentaires

@Jonathanleffler C'est un exemple simple de mise en œuvre suivant les règles énoncées par strtok mais qui confirme à quel point souhaite. Oui, Strtok n'est pas thread-coffre-fort, bien que ce soit une question complètement différente de ce que demande.


@Jonathanleffler Je n'ai jamais rien dit pour contredire ce que vous dites, je suis bien conscient des pièges qui apparaissent (ou de bas) lors de l'utilisation de strtok .


@ Philiprosénéen-refudorez-moi une question sur l'une de vos réponses. Pouvez-vous s'il vous plaît voir Stackoverflow.com/Questtions/30294129/...


Notez que cette version de strtok_single () ne renvoie pas le segment après le dernier délimiteur. Il y a une version fixe dans ce Réponse , ainsi que le code de démonstration du problème.


@Christophequintard bien repéré, je pense que cette solution particulière s'est perdue dans une révision historique (elle a été réparée, Voir Historique ) .


@Jonathanleffler Je viens de remarquer que vous avez fourni une solution pour le bogue adressé par @christophequintard , bien que fonctionnel, je pense que vous êtes Intéressé à mon correctif que je viens de modifier.


Cela ressemble à peu près à l'équivalent, bien que différent en détail. Les résultats ont l'air identiques, ce qui est bon. (Je ne peux que uppoter une fois - vous l'avez déjà eu - parce que «Écrivez le vôtre si l'outil standard ne fait pas le travail» Le conseil est entièrement valide, bien qu'il soit utilisé avec prudence. Vous devez vous assurer qu'il n'y a pas de Un outil standard alternatif que vous pouvez utiliser à la place avant de réinventer la roue.)



1
votes

Comme mentionné dans Cette réponse , vous voudrez implémenter quelque chose comme strtok vous-même . Je préfère utiliser strcspn (par opposition à strpbrk ), car il permet moins si instructions: xxx


0 commentaires

2
votes

Dernièrement, je cherchais une solution au même problème et j'ai trouvé ce fil.

Vous pouvez utiliser strgesp () . Du manuel:

La fonction StrSeP () a été introduite en remplacement de Strtok (3), Comme ce dernier ne peut pas gérer les champs vides.


0 commentaires