将char指针放入2d char指针数组的问题

时间:2015-10-06 06:26:21

标签: c

我在这里得到一些帮助,让我疯狂。

使用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

2 个答案:

答案 0 :(得分:1)

您需要分配和存储字符。使用您的代码存储字符数组line的指针,当您读取后续行时它将被覆盖。

您需要执行类似

的操作
*symbolTblChar[lblCnt]= strdup(chk);

另外,不确定你需要双字符指针

char* symbolTblChar[MAX_SYMBOLS][100];

您可以在下方使用MAX_SYMBOLS个字符串。

char* symbolTblChar[MAX_SYMBOLS];

答案 1 :(得分:0)

我想我明白你要做的是什么。除了Rohan的回答之外,你也对使用strtok感到磕磕绊绊。虽然它有点像捕获22,但由于您正在读取带有newlines分隔符号的字符串,因此您仍然可以使strtok正常工作。但是要明白,当使用strtok时,您对strtok的第一次调用使用指向字符串的指针作为其第一个参数:

chk = strtok (line, delims);

虽然对strtok的所有后续调用都使用NULL作为第一个参数:

chk = strtok (NULL, delims);

strtok的好处是它是为for循环格式解析整个字符串而量身定制的。 e.g:

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内存与使用symbolTblChar添加到strdup的每个符号相关联(它们都将其参数分配并复制到新的内存位置) )。您可以在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