在C中任意数量的空格上拆分字符串
我有一个文件,其中每个用户名和密码由不同数量的空格分隔在C中任意数量的空格上拆分字符串,c,file,parsing,C,File,Parsing,我有一个文件,其中每个用户名和密码由不同数量的空格分隔 bob passowrd1 saly password2 sam password2 void parse() { FILE*open; open = fopen("file.txt"); char line[101]; char*name; char*password; while(fgets(100,line,open)!=NULL) { name
bob passowrd1
saly password2
sam password2
void parse()
{
FILE*open;
open = fopen("file.txt");
char line[101];
char*name;
char*password;
while(fgets(100,line,open)!=NULL)
{
name = strtok(line,"*\\s");
password = strtok(NULL,"*\\s");
printf("username : %s",name);
printf("password : %s",password);
}
}
我试图使用strtok拆分字符串,但它不接受regex作为delimeter。我唯一能想到的另一种方法是通过在字符串上进行forloop并在空格后创建两个新的独立字符串来强制执行。有什么建议吗?你(和大多数受访者)对此想法太多了。strtok()在一个或多个分隔符上进行分隔,因此
name = strtok(line," ");
password = strtok(NULL," ");
将完全执行您想要的操作。如果可用,您可以使用
strep
(字符串分隔)strep
接受一组分隔符,并将逐步通过字符串将其分隔为字段。它优于strtok,因为它不保留隐藏的全局状态
void split_fields_strsep( char *string ) {
char *field;
const char *delimiters = " \t\n";
while( (field = strsep(&string, delimiters)) != NULL ) {
// Multiple spaces will show up as multiple empty fields.
// Skip them.
if( *field == '\0' ) {
continue;
}
printf("field: '%s'\n", field);
}
}
请注意,每个字段都是指向原始字符串的指针strep
将通过在每个字段末尾放置空字节将字符串拆分为字段。如果string
为foobarbaz\0
则以foo\0bar\0baz\0\0
结尾。因此,如果要保留字符串,请确保strdup
如果strep
不可用,则标准strtok
将起作用。它的工作原理类似于strsep
,将通过添加空字节来更改原始字符串
void split_fields_strtok( char *string ) {
const char *delimiters = " \t\n";
for(
char *field = strtok(string, delimiters);
field != NULL;
field = strtok(NULL, delimiters)
) {
printf("field: '%s'\n", field);
}
}
在C中任意数量的空格上拆分字符串
“*\\s”
表示对如何对令牌字符进行编码存在误解<代码>“*\\s”
查找3个字符*
、\
和s
作为标记,与strtok()
一起使用时,这些字符均不表示空格
使用显式列表解析输入行中的空白。请务必说明输入行或其他空白行的尾随
'\n'
C中的空白包括许多字符:
标准的空白字符如下:空格('
)、换页('\f'
)、新行('\n'
)、回车('\r'
)、水平制表符('\t'
)和垂直制表符('\v'
)。C11dr§7.4.1.10 2 这个输出
username : <bob>
password : <passowrd1 <-- Oops
>
用户名:
密码:我很担心你为什么要存储明文密码。@tadman这只是一个介绍类,我知道以明文存储密码是不安全的scanf
函数族忽略了某些格式(如%s
)的所有前导空格<代码>如果(fscanf(myfile,“%s%s”,name,password)!=2){/*错误输入*/}
是我的第一条评论,更好的解决方案是使用fgets
读取文件的每一行,然后应用sscanf
。这使得转储无效条目变得很容易。这里有大量的SO问题和示例代码供您查找。您还没有发布任何尝试,因此问题已脱离主题。“我正在尝试使用strtok拆分字符串,但它不接受regex作为delimeter。”-->发布该代码。没有提供VTC。strep
正是OP不想要的:它将每个单独的分隔符字符视为一个单独的分隔符。(“strep和strtok_r之间的一个区别是,如果输入字符串在一行中包含来自delimiter的多个字节,strep将为来自delimiter的每对字节返回一个空字符串。”引号来自glibc的信息文件。)<代码>strtok做了正确的事情,但是它的界面很糟糕。如果可能的话,使用@rici I accountedstrep
在代码中的行为,这里有注释和所有内容。我同意strtok,但我想提供一个标准选项,因为许多类都坚持使用C90strtok_r
至少是POSIX标准的,所以确实是这样,但我发现在分离通常需要保留空字段的单独字段时,Stresp
更易于使用,也更灵活,尽管不是在这种特殊情况下。在非标准扩展和POSIX标准函数之间,我个人会选择后者,尤其是如果它做了正确的事情。当然,您可能有一个实现附录Kstrtok\u
接口的libc。诚然,strep
非常普遍,但如今strtok\r
也很普遍。并为没有阅读您的代码而道歉。@rici您应该看到的。;)使用fgets()
填充行[]
,此快速答案将包含'\n'
在密码中,因为仅在上标记“
不足以满足OP的“在空格后创建两个新的单独字符串”要求
char line[] = "bob passowrd1\n";
char*name = strtok(line, " ");
char* password = strtok(NULL, " ");
printf("username : <%s>\n", name);
printf("password : <%s>\n", password);
username : <bob>
password : <passowrd1 <-- Oops
>