2010-08-13 42 views
7

estoy tratando de extraer el nombre de usuario de este campo URI en el código ANSI C en Linux con gccextraer una subcadena en C

mail:[email protected] 

por eso es necesario para despojar el correo: y todo después de la @. ¿Hay alguna construido en funciones en C para extraer subcadenas

Respuesta

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

char username[64]; 

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

Si es posible que tenga otra "basura" al principio (no necesariamente sólo mail:), que podría hacer algo como esto en su lugar:

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

funciona muy bien, gracias – tech74

+0

No sabía que se podía hacer esto con scanf, muy agradable :) –

+0

@ Matt: es bastante cool, ¿no es así? Lo único que echo de menos cuando uso C++ iostreams es algo equivalente a scanf's '% [whatever]' y '% [^ whatever]'. –

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; 
    } 
} 

Esto crea un puntero al carácter : (colon) dentro de la cadena. (No hace una copia de la cadena). Si se encuentra el :, señale al personaje que lo sigue. Si el : no existe, solo use el comienzo de la cadena (es decir, no asuma el prefijo mail:).

Ahora queremos quitar todo, desde el @ en adelante, por lo que hacemos una copia de la cadena (emailNameCopy) y luego cortamos el @.

El código crea un puntero al carácter @ (atSign) dentro de la cadena. Si el carácter @ existe (es decir, strchr no es NULL), el carácter en @ se establece en cero, marcando el final de la cadena. (No se realiza una copia nueva).

Devolvemos la cadena o la copiamos si se proporcionó un buffer.

+0

Tenga en cuenta que se trata de C99. No estoy seguro de si 'strdup' es estándar (siempre me confundí con ese bit), pero el hombre que lee debe decirte lo que hace y es fácil de reproducir en unas pocas líneas de código. – strager

+0

solo FWIW, no 'strdup' no es estándar (aunque es bastante común). Oficialmente, el nombre está reservado, así que si escribes uno tú mismo, obtienes un comportamiento indefinido. Cualquiera que esté realmente molesto por eso solo puede usar otro nombre que no empiece por 'str'. –

3

Puede usar también strtok. Mire este ejemplo

/* 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; 
    } 

Espero que ayude.

0

Otra solución, que no confía en ninguna posibilidad especial, y es fácilmente capaz de detectar errores es la siguiente. Tenga en cuenta que deberá liberar la cadena cuando la función extractUsername() tenga éxito.

Tenga en cuenta que en C solo navega en una secuencia de caracteres, utilizando la aritmética del puntero. Hay algunas funciones de biblioteca estándar, pero son mucho más simples que cualquier cosa capaz de extraer información de la cadena.

Todavía hay otros problemas para la detección de errores, como la presencia de más de una '@', por ejemplo. Pero esto debería ser suficiente como punto de partida.

// 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; 
} 
Cuestiones relacionadas