根据 C 中的几个设置词拆分字符串的最简单方法
Easiest way to split a string based on a few set words in C
我正在用 C 开发一个项目,我正在使用 fgets() 从文件中读取行。每个文件的格式是这样的:
Title: Name Here, Artist: Artist Here, Year Published: 2014
目前我将上面的行存储为单个字符串。问题是,我有一个名为 music_lib
的结构数组,其类型为 Song
,如下所示:
struct Song
{
char title[250];
char artist[250];
int year_published;
};
我希望能够拆分我拥有的字符串并将 Name Here
存储在 title
中,Artist Here
存储在 artist
中,2014
存储在 year_published
,同时丢弃我从文件中得到的其余字符串。
我看过 strtok()
但似乎很难,因为我想忽略 Title:
和其他单词以及逗号。有没有一种简单的方法可以让我猜找到一个子字符串 Title:
,存储在那之后的任何内容直到逗号,然后找到子字符串 Artist:
存储那里的任何内容直到我打一个逗号.. 然后做Year Published
?
也一样
使用 sscanf()
、"%[]"
(标题和艺术家)和 "%n"
定位结尾将解析缓冲区。
struct Song songa;
int n = 0;
int cnt = sscanf(buf,
" Title: %249[^,], Artist: %249[^,], Year Published: %d %n",
songa.title, songa.artist, &songa.year_published, &n);
if (cnt == EOF) Handle_EOF();
if (n > 0 && buf[n] == '[=10=]') Success();
else Handle_BadBuffer();
格式break-down" Title: %249[^,], Artist: %249[^,], Year Published: %d %n"
" "
消耗可选前导white-space.
"Title:"
消费 "Title:".
" "
消费可选 white-space.
"%249[^,]"
扫描并保存最多249个非','
char
到.title
。追加 '[=22=]'
.
", Artist:"
消费“,艺术家:”。
" "
消费可选 white-space.
"%249[^,]"
扫描并保存最多249个非','
char
到.artist
。追加 '[=22=]'
.
","
消耗“,”。
" "
消费可选 white-space。 (这里真的不需要)
"%d"
扫描并保存一个int
到.year_published
。
" "
消费可选 white-space。 (赶上\n)
"%n"
保存 buf
扫描的当前偏移量。
n
仅在扫描结束时设置。所以 non-zero 值表示成功。它应该索引到字符串的末尾。
[编辑]
我现在看到一个 similar post。最好不要将此格式与那里讨论的fscanf()
方法一起使用。
只要文件中的数据是行,首先要考虑的是fgets()
还是getline()
。这里的格式可能会被 '\n'
愚弄或在意想不到的地方嵌入 '[=22=]'
。所以最好 1) 阅读该行和 2) 然后解析它。
我正在用 C 开发一个项目,我正在使用 fgets() 从文件中读取行。每个文件的格式是这样的:
Title: Name Here, Artist: Artist Here, Year Published: 2014
目前我将上面的行存储为单个字符串。问题是,我有一个名为 music_lib
的结构数组,其类型为 Song
,如下所示:
struct Song
{
char title[250];
char artist[250];
int year_published;
};
我希望能够拆分我拥有的字符串并将 Name Here
存储在 title
中,Artist Here
存储在 artist
中,2014
存储在 year_published
,同时丢弃我从文件中得到的其余字符串。
我看过 strtok()
但似乎很难,因为我想忽略 Title:
和其他单词以及逗号。有没有一种简单的方法可以让我猜找到一个子字符串 Title:
,存储在那之后的任何内容直到逗号,然后找到子字符串 Artist:
存储那里的任何内容直到我打一个逗号.. 然后做Year Published
?
使用 sscanf()
、"%[]"
(标题和艺术家)和 "%n"
定位结尾将解析缓冲区。
struct Song songa;
int n = 0;
int cnt = sscanf(buf,
" Title: %249[^,], Artist: %249[^,], Year Published: %d %n",
songa.title, songa.artist, &songa.year_published, &n);
if (cnt == EOF) Handle_EOF();
if (n > 0 && buf[n] == '[=10=]') Success();
else Handle_BadBuffer();
格式break-down" Title: %249[^,], Artist: %249[^,], Year Published: %d %n"
" "
消耗可选前导white-space.
"Title:"
消费 "Title:".
" "
消费可选 white-space.
"%249[^,]"
扫描并保存最多249个非','
char
到.title
。追加 '[=22=]'
.
", Artist:"
消费“,艺术家:”。
" "
消费可选 white-space.
"%249[^,]"
扫描并保存最多249个非','
char
到.artist
。追加 '[=22=]'
.
","
消耗“,”。
" "
消费可选 white-space。 (这里真的不需要)
"%d"
扫描并保存一个int
到.year_published
。
" "
消费可选 white-space。 (赶上\n)
"%n"
保存 buf
扫描的当前偏移量。
n
仅在扫描结束时设置。所以 non-zero 值表示成功。它应该索引到字符串的末尾。
[编辑]
我现在看到一个 similar post。最好不要将此格式与那里讨论的fscanf()
方法一起使用。
只要文件中的数据是行,首先要考虑的是fgets()
还是getline()
。这里的格式可能会被 '\n'
愚弄或在意想不到的地方嵌入 '[=22=]'
。所以最好 1) 阅读该行和 2) 然后解析它。