我正在尝试使用gcc在Linux上从此URI字段中提取用户名的ANSI C代码。
mail:username@example.com
我需要删除邮件地址中的"mail:"以及@符号之后的所有内容。在C语言中是否有内置函数可以提取子字符串?
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 = '\0'; // To remove the '@'
// atSign[1] = '\0'; // To keep the '@'
}
if (*name) {
strcpy(*name, emailNameCopy);
} else {
*name = emailNameCopy;
}
}
这将创建一个指向字符串中的:
字符(冒号
)的指针。 (它不会复制字符串。)如果找到:
,则指向其后面的字符。 如果不存在:
,则使用字符串的开头(即假定没有mail:
前缀)。
现在我们想要从@
开始剥离所有内容,因此我们复制字符串(emailNameCopy
),然后稍后截断@
。
然后,代码将创建一个指向字符串中的@
字符(atSign)的指针。 如果存在@
字符(即strchr返回非NULL),则在@
处的字符设置为零,标记字符串的结尾。 (不会创建新副本。)
然后我们返回字符串,或者如果给出了缓冲区,则复制它。
strdup
是否标准(我一直对这一点感到困惑),但阅读手册应该能告诉您它的作用,并且可以在几行代码中轻松复制它。 - stragerstrdup
不是标准函数(虽然它非常普遍)。正式地说,这个名称是保留的,因此如果您自己编写一个 strdup
函数,就会导致未定义的行为。任何真正受到困扰的人都可以使用其他不以 str
开头的名称。 - Jerry Coffin另一种解决方案是不依赖于任何特殊功能,并且能够轻松检测错误。请注意,当函数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;
}
fscanf(fp, "nameserver %20[^\n]", address);
- Jerry Coffinnameserver
开头。大多数情况下,该文件以注释(“# Generated by NetworkManager”)或其他参数(如domains
或search
)开头。 - user2284570%*
似乎不是正确的解决方案,或者我的表达式有误。 - user2284570