在C中提取子字符串

时间:2010-08-13 16:01:06

标签: c linux

我正在尝试使用gcc

从linux上的ANSI C代码中的这个uri字段中提取用户名
mail:username@example.com

所以我需要剥离邮件:以及@之后的所有内容。 C中是否有任何内置函数来提取子字符串

4 个答案:

答案 0 :(得分:8)

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

char username[64];

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

如果你可能在开头有其他“垃圾”(不一定只是mail:),你可以这样做:

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

答案 1 :(得分:3)

您也可以使用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;
    }

希望它有所帮助。

答案 2 :(得分: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;
    }
}

这将在字符串中创建指向:字符(colon)的指针。 (它不会复制字符串。)如果找到:,则指向其后面的字符。如果:不存在,只需使用字符串的开头(即假设没有mail:前缀)。

现在我们要从@开始删除所有内容,因此我们会复制字符串(emailNameCopy),然后切断@

然后代码在字符串中创建指向@字符(atSign)的指针。如果存在@字符(即strchr返回非NULL),则@处的字符设置为零,标记字符串的结尾。 (没有制作新的副本。)

然后我们返回字符串,或者如果给出缓冲区则复制它。

答案 3 :(得分:0)

另一个不依赖于任何特殊可能性并且能够容易地检测错误的解决方案如下。请注意,当函数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;
}