Извлечение подстроки в 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;
}
