Извлечение подстроки в C

Я пытаюсь извлечь имя пользователя из этого поля uri в коде ANSI C в linux с помощью gcc

mail:username@example.com

поэтому мне нужно очистить почту: и все после @. Есть ли встроенные функции в C для извлечения подстроки

4 ответов


char *uri_field = "mail:username@example.com";

char username[64];

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

Если у вас может быть другой "мусор" в начале (не обязательно просто mail:), вы могли бы сделать что-то вроде этого:

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

вы также можете использовать strtok. Посмотрите на этот пример

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

    int main ()
    {
      char str[] ="mail:username@example.com";
      char * pch;
      pch = strtok (str," :@");
      while (pch != NULL)
      {
        printf ("%s\n",pch);
        pch = strtok (NULL, " :@");
      }
      return 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 = ''; // To remove the '@'
        // atSign[1] = '';  // To keep the '@'
    }

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

это создает указатель на : символ (colon) в строке. (Он не делает копию строки.) Если : найдено, укажите на символ после него. Если : не существует, просто используйте начало строки (т. е. предположим, что нет mail: префикс).

теперь мы хотим, чтобы очистить все от @ вперед, поэтому мы делаем копию строки (emailNameCopy) и позже отрезать @.

код затем создает указатель на @ символ (atSign) в строке. Если @ символ существует (т. е. strchr возвращает ненулевое значение), символ в @ устанавливается в ноль, отмечая конец строки. (Новая копия не сделана.)

затем мы возвращаем строку или копируем ее, если был задан буфер.


другое решение, которое не полагается на какую-либо особую возможность и легко способно обнаруживать ошибки, - это следующее. Обратите внимание, что вам придется освободить строку, когда функция extractUsername() завершится успешно.

обратите внимание, что в C вы просто перемещаетесь в последовательности символов, используя арифметику указателя. Существует несколько стандартных библиотечных функций, но они намного проще, чем что-либо, способное извлекать информацию из строки.

есть еще другие проблемы для обнаружения ошибок, такие как наличие более одного"@", например. Но этого должно быть достаточно для начала.

// Extract "mail:username@example.com"
#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:baltasarq@gmail.com";

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