Strtok 无法正常读取包含多行的字符串 [duplicate]

Strtok not working properly reading a string with multiple lines [duplicate]

提问人:Hi_Im_Frost 提问时间:4/22/2023 最后编辑:Vlad from MoscowHi_Im_Frost 更新时间:4/22/2023 访问量:49

问:

所以,我正在使用词法分析器,在所有 flex 恶作剧之后,我得到了这个文本:

ISEP 1252 "ADDRESS"
"Name1" 1253 "INFORMATICA"
"Name2" 1254 "Boilerplate1"
"Name3" 1255 "Boilerplate2"
"Name4" 1256 "Boilerplate3"
"Name5" 1257 "Boilerplate4"
"Name6" 1258 "Boilerplate5"

并将其存储在 中,然后我使用以下命令将每一行和该行的内容分开:yytextstrtok

// get first line
char* line = strtok(yytext, "\n");
// get school name
char* schoolName = strtok(line, " \t");
// get school num students
int schoolNumStudents = atoi(strtok(NULL, " \t"));
// get school address inside the quotes
char* schoolAddress = strtok(NULL, "\"");

strcpy(schools[schoolCount].name, schoolName);
schools[schoolCount].numStudents = schoolNumStudents;
strcpy(schools[schoolCount].address, schoolAddress);
//print school[schoolCount]
printf("Escola: %s\n", schools[schoolCount].name);
printf("Num alunos: %d\n", schools[schoolCount].numStudents);
printf("Morada: %s\n", schools[schoolCount].address);

// get teachers
line = strtok(NULL, "\n");
while (line != NULL) {
    char* teacherName = strtok(line, "\"");
    int teacherExt = atoi(strtok(NULL, " \t"));
    char* teacherDepartment = strtok(NULL, "\"");

    schools[schoolCount].numTeachers++;
    if(schools[schoolCount].teachers == NULL) {
        schools[schoolCount].teachers = (struct Teacher*) malloc(sizeof(struct Teacher));
    }
    else {
        schools[schoolCount].teachers = (struct Teacher*) realloc(schools[schoolCount].teachers, sizeof(struct Teacher) * (schools[schoolCount].numTeachers));
    }

    printf("Nome: %s\n", teacherName);
    printf("Ext: %d\n", teacherExt);
    printf("Departamento: %s\n", teacherDepartment);
    line = strtok(NULL, "\n");
}

schoolCount++;

这里要看到的是,作为我提供的字符串,第二个返回而不是第二行。我错过了什么吗?yytextstrtok(NULL, "\n")NULL

PS:除了我提供的代码之外,没有任何与C相关的内容,代码块嵌套在lex规则中。

我尝试将 yytext 的内容复制到不同的变量,因为 strtok 会更改变量并且 yytext 保留给 lex,但这没有完成任何事情,我尝试清除 strtok 缓冲区并在第二行中重试 strtok,也没有用。

C Lex 斯特托克

评论

1赞 Barmar 4/22/2023
您不能在不同的字符串之间交替使用,因为它会保持与当前字符串相关的静态状态,并且会就地修改字符串。这样,您可以为要分析的每个字符串保留单独的状态。strtok()strtok_r()
0赞 Neil 4/22/2023
你为什么要使用词法分析器?词法分析器将提供更详细、更快速的字符串提取技术。strtok

答:

1赞 Vlad from Moscow 4/22/2023 #1

问题是在调用子字符串行之后strtok

char* line = strtok(yytext, "\n");
// get school name
char* schoolName = strtok(line, " \t");
//..

该函数在数组中保留一个指针。所以下一个电话strtoklinestrtok

line = strtok(NULL, "\n");

引用而不是 。lineyytext

避免该问题的一种方法是计算 例如,存储在 like 中的字符串line

char *pos = yytext;

char* line = strtok( pos, "\n");
size_t n = strlen( line );
//...

并将该值用作数组内的偏移量,以便下次调用数组yytextstrtokyytext

pos += n;
line = strtok( pos, "\n");
//...