我必须解析具有以下格式的游戏文件:
ItemID = 3288 # This is a comments and begins with '#' character.
Name = "a magic sword"
Description = "It has some ancient runic inscriptions."
Flags = {MultiUse,Take,Weapon}
Attributes = {Weight=4200,WeaponType=1,WeaponAttackValue=48,WeaponDefendValue=35}
# A line can also begin with this character and it should be ignored.
我必须解析它的数据并将它们放入变量中。我已经尝试了很多东西,并且我被告知我必须逐行读取文件,然后逐个字符地读取每一行(所以我能够读到'#'字符)然后读取结果按照模式逐字逐句。我这样做了:
void ParseScriptFile(FILE* File) {
char Line[1024];
while (fgets(Line, sizeof(Line), File)) {
}
fclose(File);
}
我想我应该阅读while循环内部的行,但我不知道在到达#字符之前我将如何阅读,如果它不存在则继续循环直行。有一个简单的方法吗?
答案 0 :(得分:0)
使用sscanf,就像我为你做了两次
void ParseScriptFile(FILE* File) {
char Line[1024];
int ItemID; // variable to store ItemId
char name[40]; // string to store Name
while (fgets(Line, sizeof(Line), File)) {
sscanf(Line, "ItemID = %d", &ItemID);
sscanf(Line, "Name = %[^n]s", name); // ^n upto newline
}
printf("ItemId= %d\n", ItemID);
printf("Name= %s", name);
fclose(File);
}
答案 1 :(得分:0)
这里或多或少可行的代码。使用fgets()
读取行是正确的。然后,您可以轻松地消除空行和注释行。如果该行以注释结尾,则可以将#
转换为空字节以忽略注释。然后你需要扫描条目名称字段(假设名称部分,等号左边没有空格),=
和右边的值。
#include <stdio.h>
#include <string.h>
static
void ParseScriptFile(FILE *File)
{
char Line[1024];
while (fgets(Line, sizeof(Line), File))
{
if (Line[0] == '#' || Line[0] == '\n')
continue;
char *comment_start = strchr(Line, '#');
if (comment_start != NULL)
*comment_start = '\0';
char name[64];
char value[1024];
if (sscanf(Line, " %63s = %1023[^\n]", name, value) == 2)
printf("Name = [%s] Value = [%s]\n", name, value);
else
printf("Mal-formed line: [%s]\n", Line);
}
fclose(File);
}
int main(void)
{
ParseScriptFile(stdin);
return 0;
}
程序从标准输入读取。从您的数据文件运行的示例产生:
Name = [ItemID] Value = [3288 ]
Name = [Name] Value = ["a magic sword"]
Name = [Description] Value = ["It has some ancient runic inscriptions."]
Name = [Flags] Value = [{MultiUse,Take,Weapon}]
Name = [Attributes] Value = [{Weight=4200,WeaponType=1,WeaponAttackValue=48,WeaponDefendValue=35}]
注意ItemID值末尾的空格; #
符号前面有一个空格。
如果您需要处理本身包含#
符号的字符串,则必须更加努力(Curse = "You @##$%!" # Language, please!
)。解析诸如Attributes
的值之类的条目是单独函数的一个单独任务(可以从这个函数调用)。实际上,您应该调用一个或多个函数来处理每个名称/值对。您可能还需要将一些上下文传递给ParseScriptFile()
函数,以便可以正确保存数据。您不希望用不必要的全局变量污染干净的代码,对吗?