解析具有多个分隔符的字符串

时间:2016-02-16 21:36:55

标签: c file parsing

我如何解析文本文件: 免责声明:我不能相信我知道文本文件的内容这只是一个示例文本文件

10X16 de4 dw9 ds11 g10,7 M3,4 h6,5 p2,2 M8,5 G2,10
12X20 de7 dw10 dn13 g9,10 M7,8 h6,5 p2,2 M8,5 G2,10

这个文字文件说的是有一个尺寸为10X16的房间,东墙上的一扇门de4位于第四个位置,g10,7表示有一个小的位置10Y7X处的黄金...我不想存储任何字母,这些字母只是告诉我正在读取的数字是什么。我希望将数字存储到int个变量中,根据它是什么:黄金,怪物,药水等。

我需要将10存储为Y值并将16存储为X值,并将维度之后的其他元素存储在不同的变量中。< / p>

继承我的代码:

int main(int argc, char *argv[]) {
    //open file and read
    FILE *file = fopen(argv[1], "r");
    char line[150];
    char *dim;
    int X = 0;

    while (fgets(line, 150, file) != NULL) {
        dim = strtok(line, "X");
        X = atoi(dim);
        printf("%d\n", X);

        //parse other elements here?
        ...
    }
    fclose(file);
    return 0;
}

例如,我希望变量10中的char *roomY16中的char *roomX以及4存储在变量char *eastDoor中,这将在以后全部转换为int值。

还有像g10,7这样的元素我希望10存储为Y值,将7存储为该元素的X值。

我还应该补充说,这些字母应该用来确定价值是多少。 例如,可以使用if (string[i] = "d")路径。

我尝试过使用strtok(roomY, "X")获取X,然后使用int Y = atoi(roomY)char转换为int值。这只适用于10,但文件的其余部分我无法正确解析。有没有更有效的方法来做到这一点?

3 个答案:

答案 0 :(得分:0)

我对C:

进行字符串解析的一般建议

不要尝试使用嵌套循环,指针,不同解析模式的标志等来处理一个大函数中的所有内容。这将导致一个错误,访问冲突和难以理解的代码。

而是尝试将问题划分为更简单的任务(函数),例如拆分字符串,替换特定字符或创建子字符串。然后组合这些函数以获得所需的结果。

或者尝试找一个现有的字符串操作库。

答案 1 :(得分:0)

是。你可以使用strtok。秘诀是分隔符字符串可以包含多个分隔符。

dim = strtok(line, "X ,");

通常情况下,我告诉人们从strtok尖叫,因为它在我看来是奇怪的行为。在你的情况下,我认为这可能是合理的。

这个可以用&#39; X&#39;,空格和逗号作为分隔符。我希望能扫描17个值。

12X20 de7 dw10 dn13 g9,10 M7,8 h6,5 p2,2 M8,5 G2,10    

这个是不同的。请注意三重逗号。 Strtok认为那里没有价值。所以我希望扫描15个值。这可能是也可能不是你需要的。如果你试图解析一个csv文件,strtok将是错误的方法。

12X20 de7 dw10 dn13 g9,10 M7,8 h6,5 p2,,,5 G2,10

答案 2 :(得分:0)

我认为解析文件的最简单方法是使用strtok" "获取基本令牌,然后根据sscanf的标识符评估每个令牌。

char* tok = strtok( line, " " );
/* handle first token */
int x, y;
sscanf( tok, "%dX%d", &x, &y );

while( tok = strtok( 0, " " ) )
{
   /* handle token depending on text */
   switch( *tok )
   {
       case 'M' : 
       {
           int mx, my;
           sscanf( tok, "M%d,%d", &mx, &my );
           break;
       }
       // ...
   }
}

请注意,这只是解决方案的草图。您应该将switch移动到某个eval_token函数以及每个案例中。