2010-08-13 6 views
7

je suis en train d'extraire le nom d'utilisateur de ce champ uri dans le code ANSI C sous Linux avec gccExtrait une sous-chaîne en C

mail:[email protected] 

donc je dois dépouiller le courrier: et tout ce qui suit le @. Y at-il construit en fonctions en C pour extraire des sous-chaînes

Répondre

8
char *uri_field = "mail:[email protected]"; 

char username[64]; 

sscanf(uri_field, "mail:%63[^@]", username); 

Si vous pourriez avoir d'autres « junk » au début (pas nécessairement juste mail:), vous pouvez faire quelque chose comme ceci:

sscanf(uri_field, "%*[^:]:%63[^@]", username); 
+0

fonctionne très bien, merci – tech74

+0

ne savais pas que vous pouvez le faire avec scanf, très agréable :) –

+0

@ Matt: il est assez cool, non? La seule chose qui me manque le plus lorsque j'utilise C++ iostreams est quelque chose d'équivalent à '% [whatever]' et '% [^ whatever]' de scanf. –

0
void getEmailName(const char *email, char **name /* out */) { 
    if (!name) { 
     return; 
    } 

    const char *emailName = strchr(email, ':'); 

    if (emailName) { 
     ++emailName; 
    } else { 
     emailName = email; 
    } 

    char *emailNameCopy = strdup(emailName); 

    if (!emailNameCopy) { 
     *name = NULL; 

     return; 
    } 

    char *atSign = strchr(emailNameCopy, '@'); 

    if (atSign) { 
     *atSign = '\0'; // To remove the '@' 
     // atSign[1] = '\0'; // To keep the '@' 
    } 

    if (*name) { 
     strcpy(*name, emailNameCopy); 
    } else { 
     *name = emailNameCopy; 
    } 
} 

Cela crée un pointeur vers le caractère : (colon) dans la chaîne. (Il ne fait pas une copie de la chaîne.) Si le : est trouvé, pointez sur le caractère après lui. Si le : n'existe pas, utilisez simplement le début de la chaîne (c'est-à-dire n'attribuez pas le préfixe mail:).

Maintenant, nous voulons supprimer tout à partir de @, donc nous faisons une copie de la chaîne (emailNameCopy) et plus tard, couper le @.

Le code crée ensuite un pointeur sur le caractère @ (atSign) dans la chaîne. Si le caractère @ existe (c'est-à-dire que strchr renvoie non-NULL), le caractère au @ est défini sur zéro, marquant la fin de la chaîne. (Une nouvelle copie n'est pas faite.)

Nous retournons alors la chaîne, ou la copions si un tampon a été donné.

+0

Notez que c'est C99. Je ne suis pas sûr si 'strdup' est standard (j'étais toujours confus à propos de ce bit), mais lire l'homme devrait vous dire ce qu'il fait et il est facile de le reproduire dans quelques lignes de code. – strager

+0

juste FWIW, aucun 'strdup' n'est pas standard (bien que ce soit assez commun). Officiellement, le nom est réservé, donc si vous en écrivez un vous-même, vous obtenez un comportement indéfini. Quiconque est vraiment dérangé par cela peut simplement utiliser un autre nom qui ne commence pas par 'str'. –

3

Vous pouvez également utiliser strtok. Regardez cet exemple

/* strtok example */ 
#include <stdio.h> 
#include <string.h> 

    int main() 
    { 
     char str[] ="mail:[email protected]"; 
     char * pch; 
     pch = strtok (str," :@"); 
     while (pch != NULL) 
     { 
     printf ("%s\n",pch); 
     pch = strtok (NULL, " :@"); 
     } 
     return 0; 
    } 

Espérons que ça aide.

0

Une autre solution, qui ne repose sur aucune possibilité particulière, et qui est facilement capable de détecter des erreurs est la suivante. Notez que vous devrez libérer la chaîne lorsque la fonction extractUsername() aura abouti.

Notez que dans C vous naviguez simplement dans une séquence de caractères, en utilisant l'arithmétique du pointeur. Il existe quelques fonctions de bibliothèque standard, mais elles sont beaucoup plus simples que tout ce qui peut extraire des informations de la chaîne.

Il existe encore d'autres problèmes de détection d'erreur, tels que la présence de plusieurs '@', par exemple. Mais cela devrait être suffisant comme point de départ.

// Extract "mail:[email protected]" 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

const char * MailPrefix = "mail:"; 
const char AtSign = '@'; 

char * extractUserName(const char * eMail) 
{ 
    int length = strlen(eMail); 
    char * posAtSign = strrchr(eMail, AtSign); 
    int prefixLength = strlen(MailPrefix); 

    char * toret = (char *) malloc(length + 1); 
    if (toret != NULL 
     && posAtSign != NULL 
     && strncmp(eMail, MailPrefix, prefixLength) == 0) 
    { 
     memset(toret, 0, length +1); 
     strncpy(toret, eMail + prefixLength, posAtSign - prefixLength - eMail); 
    } 
    else { 
     free(toret); 
     toret = NULL; 
    } 

    return toret; 
} 

int main() 
{ 
    const char * test = "mail:[email protected]"; 

    char * userName = extractUserName(test); 

    if (userName != NULL) { 
     printf("User name: '%s'\n", userName); 
     free(userName); 
    } else { 
     fprintf(stderr, "Error: invalid e.mail address\n"); 
     return EXIT_FAILURE; 
    } 

    return EXIT_SUCCESS; 
}