簡體   English   中英

在C中解析.txt文件

[英]Parsing .txt file in C

我試圖通過C中的.txt文件進行解析。這是我到目前為止所擁有的

void parser()
{
FILE * rooms;
char * theString;
char * theToken;

char a[ROOM_STRING_LENGTH];

rooms = fopen("assets/rooms.txt", "r");

if(rooms == NULL)
{
    printf("error opening file\n");
}
while(fgets(a, ROOM_STRING_LENGTH, rooms) != NULL)
{

    theString = malloc((sizeof(char)*(strlen(a)+1)));
    strcpy(theString, a);
    theToken = strtok(theString, " ");
    while (theToken != NULL)
    {
        printf("the next token: %s\n", theToken);
        theToken = strtok(NULL, " ");
        if(theToken[0] == 'd')
        {
            doorParser(theToken);       
        }

        else if(theToken[0] == 'g' || theToken[0] == 'm' || theToken[0] == 'p' || theToken[0] == 'h')
        {
             iconParser(theToken);
        }
    }
    if(theToken == NULL)
    {

    }

}
free(theString);
fclose(rooms);
}
void iconParser(char * theToken)
{
int k;
int item;
char posX;
char posY;
while(k <= (strlen(theToken)))
{
    switch(theToken[k])
    {
        case 'g':
        item = 1;
        posY = theToken[1];
        posX = theToken[3];
        printf("the item: %d, the y position: %c, the x position: %c\n", item, posY, posX);
        break;

        case 'm':
        item = 2;
        posY = theToken[1];
        posX = theToken[3];
        break;

        case 'p':
        item = 3;
        posY = theToken[1];
        posX = theToken[3];
        break;

        case 'h':
        item = 4;
        posY = theToken[1];
        posX = theToken[3];
        break;
    }
    k++;
}
}


void doorParser(char * theToken)
{
int side;
char place;
switch(theToken[1])
{
    case 'e':
    {
        side = 1;
        place = theToken[2];
        printf("the side: %d, the place: %c\n", side, place);
        break;
    }
    case 'w':
    {
        side = 2;
        place = theToken[2];
        break;
    }
    case 's':
    {
        side = 3;
        place = theToken[2];
        break;
    }
    case 'n':
    {
        side = 4;
        place = theToken[2];
        break;
    }
    default:
    {

    } 
} 
}

這是我的.txt文件:

12X6 de8 dw3 ds5 g8,7 m3,4 p2,2 h2,2
12X6 de8 dw3 ds5 g8,7 m3,4 p2,2 h2,4
12X6 de8 dw3 ds5 g8,7 m3,4 p2,2 h2,6
12X6 de8 dw3 ds5 g8,7 m3,4 p2,2 h2,10
12X6 de8 dw3 ds5 g8,7 m3,4 p2,2 h2,12
12X6 de8 dw3 ds5 g8,7 m3,4 p2,2 h2,14

我現在遇到的問題是,在它運行一行或然后運行.txt文件然后我得到一個分段錯誤,我也想知道如何轉換字符串的某個值(即一個char)成一個int值

首先,你的循環結構沒有任何意義:

while (theToken != NULL)
{
    printf("the next token: %s\n", theToken);
    theToken = strtok(NULL, " ");
    if(theToken[0] == 'd')  <<< This is dereferencing NULL after last token!

您正在使用while條件檢查theToken是否為NULL ,然后您獲得下一個標記並立即使用它(通過嘗試查找其第0個字符),即使它是NULL

使用strtok的慣用方法是

for (tok = strtok(str, " "); tok; tok = strtok(NULL, " "))
{
   // Process the token here.

對於第二部分 - 將字符串轉換為int - 您可以谷歌foro函數實現。 例如, http://www.geeksforgeeks.org/write-your-own-atoi/ int atoi(char * str) - 確實如此將“1998”轉換為1998年

在這種情況下看起來也像:

while(fgets(a, ROOM_STRING_LENGTH, rooms) != NULL)
{
   while((c=fgetc(rooms))!='\n')
   {
     roomString[i] = c;
     i++;
   }
   ...etc

你最終錯過了第一行(和所有其他奇數行)beacuse fgets讀取第一行(並且你不使用這個結果),然后“while((c = fgetc(rooms))!='\\ n') “在這里閱讀第二行......

所以,我認為你需要做的是用“fgets(a,ROOM_STRING_LENGTH,rooms)”來解析你讀到的“a”。 我可能錯了,但我認為“strlen(a)”會給你實際的行長 - 而不是緩沖區的大小。 所以你可以開始解析“a”而不是將所有內容復制到roomString中

噢,我可能會看到Seg故障的潛在原因 - 在循環中

while((c=fgetc(rooms))!='\n')
{
    roomString[i] = c;
    i++;
} 

“i”增加而且你永遠不會“沖洗”它,在每個這樣的循環之前應該有i = 0,否則你的“i”會隨着每次迭代的更大而繼續增加“while(fgets(a,ROOM_STRING_LENGTH,rooms)!= NULL)“循環 - 這是你可以越過你的”char roomString [ROOM_STRING_LENGTH];“ 緩沖 ...

正如Gene在評論中建議的那樣,即使在最內部的while循環中ti為NULL,也嘗試訪問theToken [0]元素,嘗試替換代碼:

theToken = strtok(theString, " ");
while (theToken != NULL)
{
    printf("the next token: %s\n", theToken);
    theToken = strtok(NULL, " ");
    if(theToken[0] == 'd')
    {
        doorParser(theToken);       
    }

    else if(theToken[0] == 'g' || theToken[0] == 'm' || theToken[0] == 'p' || theToken[0] == 'h')
    {
         iconParser(theToken);
    }
}
if(theToken == NULL)
{

}

以下是:

theToken = strtok(theString, " ");
while (theToken != NULL)
{
    printf("the next token: %s\n", theToken);
    if(theToken[0] == 'd')
    {
        doorParser(theToken);       
    }

    else if(theToken[0] == 'g' || theToken[0] == 'm' || theToken[0] == 'p' || theToken[0] == 'h')
    {
         iconParser(theToken);
    }
    /* invoking strtok here is "safe" because you check if't NULL right after in the while loop condition */
    theToken = strtok(NULL, " ");
}
if(theToken == NULL)
{
   printf("string is over no more tokens! next line ...");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM