C++ 如何仅解析字符串的最后一个字符?

C++ 如何仅解析字符串的最后一个字符?,c++,c,string,parsing,strtok,C++,C,String,Parsing,Strtok,我目前正在做的是从输入的mp3字符串中解析出歌曲标题和艺术家 字符串的格式为“artist title.mp3”,我们的老师向我们提供了此信息,并确保任何歌曲名中都不会有-字符,但标题中可能有或可能没有字符 我现在编写的方法与strtok()函数完美结合,只抓取这些字符前面的内容,并将它们放入title/artist字段 像这样: //Parse out the artist and title from the song char* artistName = strtok(song,

我目前正在做的是从输入的mp3字符串中解析出歌曲标题和艺术家

字符串的格式为“artist title.mp3”,我们的老师向我们提供了此信息,并确保任何歌曲名中都不会有
-
字符,但标题中可能有或可能没有
字符

我现在编写的方法与
strtok()
函数完美结合,只抓取这些字符前面的内容,并将它们放入title/artist字段

像这样:

//Parse out the artist and title from the song
    char* artistName = strtok(song, "-");
    char* songName = strtok(NULL, ".");

    //Allocate a new block of memory to the blocks songInfo fields with the correct size
    newBlock->songInfo.artist = (char*)malloc(sizeof(char) * strlen(artistName) + kNullTerminator);
    newBlock->songInfo.title = (char*)malloc(sizeof(char) * strlen(songName) + kNullTerminator);

唯一的问题是,如果标题名称中有一个点,它将无法识别完整的字符串作为标题,它会将其截断。我想知道的是,如何使用strtok()获取最后一个
,而不仅仅是它找到的第一个点?

首先,您可以使用查找来查找输入中最后出现的


也就是说,使用strtok(),您也可以完成此操作。只需继续解析同一个字符串,直到你得到null,然后考虑最后一次的情况。

你可能实际上是通过使用<代码> Strtok artist title.mp3,并保证字符串中只有一个
'-'
(即分隔符),则您已经拥有将字符串解析为artist和title而不使用
strtok
所需的所有信息

想想看。你所需要做的就是读每一行。您首先要确认该行以
.mp3
结尾,并且该行的长度至少为
8
个字符(如果使用面向行的输入函数(如
fgets
getline
)读取)。为什么?

如果行少于
8个字符,则不能有艺术家、分隔符、标题和.mp3(带尾随换行符)。只需调用
strlen
即可获得长度。您可以通过从
行[len-5]
开始简单调用
strncmp
来确认字符串的最后4个字符是
.mp3

接下来,您需要确认该行包含一个
'-'
分隔符。对
strchr
的简单调用既可以确认分隔符的存在,又可以返回一个指向该行中分隔符位置的指针

知道行的长度和分隔符的位置后,您的行已被解析。您只需在
'-'
分隔符和
'.
(在
.mp3
中)处对字符串的各个部分进行nul终止,然后将这些部分复制到存储库中,以供
艺术家和
标题使用

在一个简单的示例中,将这些部分组合在一起,您可以执行以下操作:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char *artist;
    char *title;
} track;

enum { MAXS = 128, MAXC = 256 };

int main (int argc, char **argv) {

    track album[MAXS] = {{NULL}, {NULL}};
    char line[MAXC] = {0};
    size_t i, idx = 0;
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    while (fgets (line, MAXC, fp)) 
    {
        char *p = strchr (line, '-');       /* pointer to '-'    */
        size_t len = strlen (line);         /* length of line    */

        if (!p || len < 8 || strncmp (&line[len-5], ".mp3", 4))
            continue;                       /* skip invalid line */

        *p = 0;                             /* nul-terminate at '-' */
        line[len-5] = 0;                    /* nul-terminate at '.' */

        album[idx].artist = strdup (line);  /* alloc/copy artist */
        album[idx++].title = strdup (p + 1);/* alloc/copy title  */

        if (idx == MAXS) {  /* check index against max songs */
            fprintf (stderr, "warning: MAXS songs reached.\n");
            break;
        }
    }

    printf ("\nArtists & Titles\n");
    for (i = 0; i < idx; i++)
        printf ("\n artist : %s\n title  : %s\n",
                album[i].artist, album[i].title);

    for (i = 0; i < idx; i++) {
        free (album[i].artist);
        free (album[i].title);
    }

    return 0;
}
输出

$ ./bin/fgets_artist_title dat/artist-title.txt

Artists & Titles

 artist : SO Superband
 title  : Against the String

 artist : .30 Caliber Quartet
 title  : Songs to Die For

 artist : Dot.com.duet
 title  : Internet Harmony

您可以添加额外的验证来防止短读,或者检查大写字母
.MP3
,等等,但是对于基本逻辑,您不能比只使用给定的信息、涉及的长度和指针简单得多。如果有问题,请告诉我。< /P>是C还是C++?如果C++ <代码> STD:::String::FordHythistOf()< C++ > ->代码> STD::String < /C>。C或C++?“<代码> MalCube()/代码>的明显用法,这可能与C.@ SuravgHoh相关:你是一个非常乐观的人,不是吗?”也许那些没有说明相关语言的问题应该以“太宽泛”来结束。strrchr是一个好办法。strtok将通过将点设置为零字节来破坏标题,我认为,这似乎不是作者想要指出的,但这只是意味着,如果他确实有一个中间标题
,则将由OP将各个部分(个人
strtok
返回)放在一起。
$ cat dat/artist-title.txt
This is a collection of songs artist-title in mp3 format

# favorite artists
SO Superband-Against the String.mp3
# a capella
.30 Caliber Quartet-Songs to Die For.mp3
# duets
Dot.com.duet-Internet Harmony.mp3
$ ./bin/fgets_artist_title dat/artist-title.txt

Artists & Titles

 artist : SO Superband
 title  : Against the String

 artist : .30 Caliber Quartet
 title  : Songs to Die For

 artist : Dot.com.duet
 title  : Internet Harmony