我有一個文本檔案,其中包含多個不同長度的字串,我需要將這些字串拆分為標記。最好使用strtok拆分這些字串以及如何計算令牌?
檔案中的字串示例
Emma Stone#1169876#COMP242#COMP333#COMP336#COMP133#COMP231
Emma Watson#1169875#COMP336#COMP2421#COMP231#COMP338#CCOMP3351
Kevin Hart#1146542#COMP142#COMP242#COMP231#COMP336#COMP331#COMP334
George Clooney#1164561#COMP336#COMP2421#COMP231#COMP338#CCOMP3351
Matt Damon#1118764#COMP439#COMP4232#COMP422#COMP311#COMP338
Johnny Depp#1019876#COMP311#COMP242#COMP233#COMP3431#COMP333#COMP432
uj5u.com熱心網友回復:
一般來說,使用strtok是一個很好的解決問題的方法:
#include <stdio.h>
#include <string.h>
int main( void )
{
char line[] =
"Emma Stone#1169876#COMP242#COMP333#COMP336#COMP133#COMP231";
char *p;
int num_tokens = 0;
p = strtok( line, "#" );
while ( p != NULL )
{
num_tokens ;
printf( "Token #%d: %s\n", num_tokens, p );
p = strtok( NULL, "#" );
}
}
該程式具有以下輸出:
Token #1: Emma Stone
Token #2: 1169876
Token #3: COMP242
Token #4: COMP333
Token #5: COMP336
Token #6: COMP133
Token #7: COMP231
但是,使用的一個缺點strtok是它具有破壞性,因為它通過用#終止空字符替換分隔符來修改字串。如果你不想要這個,那么你可以使用strchr:
#include <stdio.h>
#include <string.h>
int main( void )
{
const char *const line =
"Emma Stone#1169876#COMP242#COMP333#COMP336#COMP133#COMP231";
const char *p = line, *q;
int num_tokens = 1;
while ( ( q = strchr( p, '#' ) ) != NULL )
{
printf( "Token #%d: %.*s\n", num_tokens, q-p, p );
num_tokens ;
p = q 1;
}
printf( "Token #%d: %s\n", num_tokens, p );
}
這個程式與第一個程式有相同的輸出:
Token #1: Emma Stone
Token #2: 1169876
Token #3: COMP242
Token #4: COMP333
Token #5: COMP336
Token #6: COMP133
Token #7: COMP231
另一個缺點strtok是它不是可重入的或執行緒安全的,而是strchr。然而,一些平臺提供了一個功能strtok_r,它沒有這些缺點。但該功能仍然具有破壞性的缺點。
uj5u.com熱心網友回復:
是的,您應該使用strtok拆分這些字串。
在
我如何計算令牌
您可以簡單地在內部添加一個計數器while并在每次迭代中將其加一以獲得令牌總數。
#include <stdio.h>
#include <string.h>
int main(void) {
char string[] = "Hello world this is a simple string";
char *token = strtok(string, " ");
int count = 0;
while (token != NULL) {
count ;
token = strtok(NULL, " ");
}
printf("Total number of tokens = %d", count);
return 0;
}
uj5u.com熱心網友回復:
您還可以撰寫自己的函式來處理這個非常瑣碎的拆分:
char **split(char *str, char **argv, size_t *argc, const char delim)
{
*argc = 0;
if(*str && *str)
{
argv[0] = str;
*argc = 1;
while(*str)
{
if(*str == delim)
{
*str = 0;
str ;
if(*str)
{
argv[*argc] = str;
*argc = 1;
continue;
}
}
str ;
}
}
return argv;
}
int main(void)
{
char *argv[10];
size_t argc;
char str[] = "Emma Stone#1169876#COMP242#COMP333#COMP336#COMP133#COMP231";
split(str, argv, &argc, '#');
printf("Numner of substrings: %zu\n", argc);
for(size_t i = 0; i < argc; i )
printf("token [%2zu] = `%s`\n", i, argv[i]);
}
https://godbolt.org/z/b1aarnfWs
備注:與 strtok 相同,它需要str我修改。str將被修改。
uj5u.com熱心網友回復:
strtok()很少是任何事情的正確工具。在這種情況下,不清楚一個序列 of##是否等同于單個#以及#出現在行首或行尾的 a 是否應被忽略......
strtok() 對這些可能不是預期行為的情況做出強有力的假設。
此外,strtok()修改其字串引數并使用隱藏的靜態狀態,這使其在多執行緒程式中不安全,并且在嵌套用例中容易出現編程錯誤。strtok_r(),在可用的情況下,解決了這些問題,但語意仍然有些違反直覺。
為了您的目的,您必須精確定義什么是標記和分隔符。如果允許空令牌,strtok()絕對不是解決方案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/331934.html
上一篇:與switch相比,為什么elseif產生不同的結果?
下一篇:C程式無法同時執行多條陳述句
