Извлечь подстроку в C - PullRequest
       2

Извлечь подстроку в C

7 голосов
/ 13 августа 2010

Я пытаюсь извлечь имя пользователя из этого поля URI в коде ANSI C для Linux, используя gcc

mail:username@example.com

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

Ответы [ 4 ]

8 голосов
/ 13 августа 2010
char *uri_field = "mail:username@example.com";

char username[64];

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

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

3 голосов
/ 13 августа 2010

Вы также можете использовать 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;
    }

Надеюсь, это поможет.

0 голосов
/ 13 августа 2010

Другое решение, которое не зависит от какой-либо особой возможности и легко способно обнаруживать ошибки, является следующим. Обратите внимание, что вам нужно будет освободить строку, когда функция 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;
}
0 голосов
/ 13 августа 2010
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;
    }
}

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...