2015-10-06 87 views
0

我想在這裏得到一些幫助,讓我瘋狂。問題把字符指針放入二維數組的char指針

使用strtok分割我的線條的大文件。我試圖將第一部分分開,並將其保存到我的symbolTblChar [lblCnt]中。我似乎無法明白的是爲什麼,從文件中提取後,我的輸出變得如此怪異

INPUT

"SPACE \n LINE \n A1 \n A2" 

代碼

char* symbolTblChar[MAX_SYMBOLS][100]; 
int lblCnt = 0; 
char line[LINE_SIZE]; 
char* chk; 


    while(fgets(line, sizeof line, fp) != NULL) {         
      chk = (char*)strtok(line, delims); 
      printf("Adding %s to symbol table", chk); 
      *symbolTblChar[lblCnt]=chk + '\0'; 
      lblCnt++; 
      int t; 
      for(t = 0; t < lblCnt; t++) 
        printf("%s\n", *symbolTblChar[t]);      
    } 

輸出:

Adding SPACE to symbol table 
    Adding LINE to symbol table 
    LINE 
    Adding A1 to symbol table 
    A1 
    A1 
    Adding A2 to symbol table 
    A2 
    A2 
    A2 
+1

指針不是字符串並且在C.沒有預先做好串類這恐怕整個代碼沒有按沒有任何意義。特別是'* symbolTblChar [lblCnt] = chk +'\ 0';'沒有任何意義,並且暗示你相信你在做一些硬拷貝而不是你,你只是分配地址。在嘗試此操作之前,我會退後一步研究指針和數組。 – Lundin

+0

感謝您的建議。硬+ NULL是一個絕望的嘗試,從C#開始,當我開始感到沮喪時,結轉 –

回答

1

您需要分配和存儲字符。使用您的代碼,您正在存儲字符數組line的指針,並且在讀取後續行時它將被覆蓋。

你需要做的是這樣

*symbolTblChar[lblCnt]= strdup(chk); 

而且,不知道你需要雙字符指針作爲

char* symbolTblChar[MAX_SYMBOLS][100]; 

你可以用下面這些工作將存儲MAX_SYMBOLS數量的字符串。

char* symbolTblChar[MAX_SYMBOLS]; 
+0

謝謝,strdup伎倆。因爲我可以從多個位置訪問指針數組並獲得相同的答案,所以我被拋棄了。儘管一個編輯。我必須刪除您的第一行建議的解除引用,否則我得到一個int指針投射問題。 –

+0

@BryanS。,是的,如果你按照這個建議,那麼你需要改變你使用'symbolTblChar'的方式,也就是不要去引用它。 – Rohan

+0

我建議使用malloc和memcpy/strcpy代替strdup,因爲strdup是非標準的。 – Lundin

0

我想我明白你在做什麼。除了Rohan的回答之外,你還在勉強使用strtok。雖然它有點像22,但是由於您正在讀取一個由符號newlines分隔的字符串,因此仍然可以使strtok正常工作。明白不過,使用strtok的時候,你要strtok首先調用使用指向字符串的第一個參數:

chk = strtok (line, delims); 

,而所有後續調用strtok使用NULL的第一個參數:

chk = strtok (NULL, delims); 

strtok有什麼好處,它是爲了解析for循環格式中的整個字符串而量身定製的。例如爲:

for (chk = strtok (line, delims); chk; chk = strtok (NULL, delims)) 

把它們一起,和清理symbolTblChar[MAX_SYMBOLS]簡單地是一個指針數組,以char,重新安排邏輯位,提供了以下示例。我猜你會需要LINE_SIZE什麼,什麼會爲MAX_SYMBOLS工作(根據需要調整):

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

#define LINE_SIZE 128 
#define MAX_SYMBOLS 32 

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

    char *symbolTblChar[MAX_SYMBOLS] = {NULL}; 
    char line[LINE_SIZE] = {0}; 
    char *chk = NULL; 
    char delims[] = " \n"; 
    int lblCnt = 0; 
    int t = 0; 
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin; 

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

    printf ("\nCollecting Symbols:\n"); 
    while (fgets (line, LINE_SIZE, fp)) 
    {         
     for (chk = strtok (line, delims); chk; chk = strtok (NULL, delims)) { 
      printf (" Adding %s to symbol table\n", chk); 
      symbolTblChar[lblCnt] = strdup (chk); 
      lblCnt++; 

      /* check for MAX_SYMBOLS */ 
      if (lblCnt == MAX_SYMBOLS) { 
       fprintf (stderr, "warining: MAX_SYMBOLS limit reached.\n"); 
       break; 
      } 
     } 
    } 

    /* close file if not stdin */ 
    if (fp != stdin) fclose (fp); 

    /* output */ 
    printf ("\nSymbols:\n"); 
    for (t = 0; t < lblCnt; t++) 
     printf(" %s\n", symbolTblChar[t]); 

    /* free allocated memory */ 
    for (t = 0; t < lblCnt; t++) 
     free (symbolTblChar[t]); 

    return 0; 
} 

輸出

使用您的樣品輸入提供:

$ printf "SPACE \n LINE \n A1 \n A2\n" | ./bin/symbltbl 

Collecting Symbols: 
    Adding SPACE to symbol table 
    Adding LINE to symbol table 
    Adding A1 to symbol table 
    Adding A2 to symbol table 

Symbols: 
    SPACE 
    LINE 
    A1 
    A2 

注:當您完成該操作後,您當然可以刪除Adding X ...中間打印行。現在,儘管可能不明顯,但您需要free與使用strdup(它們都將其參數分配並複製到新內存位置)的每個符號相關聯的內存添加到symbolTblChar。您可以看到發生在main末尾的情況。

如果這不是你想要的,請告訴我。看完這個問題和你在做什麼後,這看起來就像你的邏輯意圖。如果您有任何問題,請告訴我。

文件輸入:注意到,您也可以提供一個輸入文件名作爲第一個參數的程序,程序會從文件,而不是stdin閱讀。例如,輸入文件:

$ cat symbols.txt 
    SPACE 
    LINE 
    A1 
    A2 

輸出從文件讀取

$ /bin/symbltbl symbols.txt 

Collecting Symbols: 
    Adding SPACE to symbol table 
    Adding LINE to symbol table 
    Adding A1 to symbol table 
    Adding A2 to symbol table 

Symbols: 
    SPACE 
    LINE 
    A1 
    A2