0

我已经尝试了几个小时将此文件读入我想在我的 C 编程项目中使用的结构。我无法让它与结构正常工作。

这是我要读入的文件:

# category
- word to guess
*information to help you to guess the word

- another word to guess
* information to help you to guess the word

# another category
- word to guess
*information to help you to guess the word

- another word to guess
* information to help you to guess the word

这是我的代码(似乎不起作用):

char retazec[50]; // here goes the read in string from the file
char kategoria[50]; // here the category name is stored

i = 0; // index for the array of structures
j = 1;
while (!feof(otazky)) {
    fgets(retazec, 50, otazky);
    if (strchr(retazec, '#') != NULL) {
        printf("%s", retazec);
        printf("%d\n", i);
        slova[i].kategoria = retazec;
        strcpy(kategoria, retazec);
    }
    if (strchr(retazec, '-') != NULL) {
        printf("%s", retazec);
        printf("%d\n", i-j);
        slova[i-j].slovo = retazec;
        j++;
    }
    if (strchr(retazec, '*') != NULL) {
        printf("%s", retazec);
        printf("%d\n", i-j);
        slova[i-j].napoveda = retazec;
        j++;
    }
    i++;
}

putchar('\n');
putchar('\n');
printf("%s", slova[0].kategoria);
printf("%s", slova[0].slovo);
printf("%s", slova[0].napoveda);

我希望它如何工作

我有i变量来存储结构数组的索引。该j变量用于更正数组索引。

  1. 读取第一个字符串(#类别)

  2. 如果确实包含 a '\#',请记住它是什么类别并将其放入slova[i].kategoria( iis 0)

  3. 它检查其他两个并递增i

  4. 读取第二个字符串(-要猜测的单词)

  5. 第一个if是假的,在第二个中,如果字符串包含 a '-',则将其放入slova[i-j].slovo( iis 1, jis 1 so i - j = 0) 并且它会递增j,因为在下一步中,当程序要读取信息以帮助用户时猜测,i也将是 2,ji - j再次给我们 0。正如我所想,这 3 个字符串应该在slova[0]结构中。但它不起作用,我不知道为什么。

如果有人知道答案,请帮助我。

4

3 回答 3

2

当您在文件中循环时,您正在将数据读入retazec缓冲区,然后您测试它是否是一个类别、单词或提示。当它是一个类别时,您将类别名称复制到

strcpy(kategoria, retazec)

然而,当它是一个单词或一个提示时,你只是设置了一个指向读取缓冲区的指针

slova[i-j].napoveda = retazec;

但是下一次读取会破坏该值(覆盖它)。

您应该复制值,而不是在那里分配指针。您不能分配字符串,您必须复制它们。

于 2013-04-11T20:11:00.860 回答
1

万能的天啊 正是这样的项目让我想起了 C++ 的一些好处,即向量和列表。要么会大大简化任务。

在我看来,您需要保留(a)类别的链接列表读取(b)每个类别中的链接列表,其中包含该猫的单词/提示对。

我只是费心制作每个类别中的单词/提示的链接列表。每当遇到新类别时,我都会简单地覆盖前一个类别。我也会像偷走的火箭燃料一样燃烧记忆。:-D

在处理类别时,您可能希望遵循我用于项目链表的模式,或者您可以选择使用数组和 realloc。

无论如何,希望它对您有所帮助和有用。:-)

主程序

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

struct sItem
{
    char    *wordToGuess;
    char    *wordGuessHint;
    sItem   *next;
};

struct sCat
{
    char    *categoryName;
    sItem   *itemList;
};

sItem *newItem(char *word, char *hint)
{
    sItem *tmp;
    tmp = (sItem*)malloc(sizeof(sItem));
    tmp->wordToGuess = word;
    tmp->wordGuessHint = hint;
    return tmp;
}

sItem *getTail(sItem *head)
{
    sItem *tmp;
    tmp = head;
    while (tmp->next != NULL)
        tmp = tmp->next;
    return tmp;
}

void addListItem(sItem **listHead, char *word, char *wordHint)
{
    sItem *tmp1, *theNewNode = newItem(word, wordHint);

    // list is empty
    if ((*listHead) == NULL)
        (*listHead) = theNewNode;

    // find end of list and add entry there
    else
    {
        tmp1 = getTail(*listHead);
        tmp1->next = theNewNode;
    }
}

// display a list of sItems (each category has it's own list)
void printList(sItem *listHead)
{
    sItem *tmp = listHead;
    while (tmp != NULL)
    {
        printf("Word: %s\n", tmp->wordToGuess);
        printf("Hint: %s\n", tmp->wordGuessHint);
        printf("\n");
        tmp = tmp->next;
    }
}

void printCategory(sCat &cat)
{
    printf("Category: %s\n", cat.categoryName);
    printList(cat.itemList);
    printf("\n");
}

int main(int argCount, char *argValues[])
{
    char lineBuffer[256];
    sCat curCategory;
    char *curStr=NULL, *curWord=NULL, *curHint=NULL;
    bool isFirst = true;
    FILE *fp = fopen("data.txt", "r");
    curCategory.itemList = NULL;
    while (fgets(lineBuffer, 255, fp) != NULL)
    {
        // 1. trim trailing new-line character
        lineBuffer[ strlen(lineBuffer) - 1] = 0;
        // 2. set pointer to point to first char of 'data' in the line
        curStr = lineBuffer + 2;
        switch (lineBuffer[0])
        {
            case '#':                       // category
                if (isFirst != true)
                {
                    printCategory(curCategory);
                }
                curCategory.categoryName = strdup(curStr);
                curCategory.itemList = NULL;
//                printf("# [%s]\n", curStr);
                isFirst = false;
                break;
            case '-':                       // word
                curWord = strdup(curStr);
//                printf("- [%s]\n", curStr);
                break;
            case '*':                       // hint
                curHint = strdup(curStr);
                addListItem(&curCategory.itemList, curWord, curHint);
 //               printf("* [%s]\n", curStr);
                break;
        }
    }
    fclose(fp);
    printCategory(curCategory);
}

数据.txt

# Animals
- Zebra
* Black + white stripes

- Girraffe
* Tall orange

# Cars
- Mustang
* A real 'animal' of a car

- Lamborghini Diablo
* A devillishly good ride.

输出:

Category: Animals
Word: Zebra
Hint: Black + white stripes

Word: Girraffe
Hint: Tall orange


Category: Cars
Word: Mustang
Hint: A real 'animal' of a car

Word: Lamborghini Diablo
Hint: A devillishly good ride.



Process returned 0 (0x0)   execution time : 0.080 s
Press any key to continue.
于 2013-04-11T21:25:33.837 回答
0

谢谢 K Scott Piel 和 enhzflep
因为我不能使用链表,因为这是一个学校项目,他们没有教我们如何使用它们,所以我想出了这个(令人惊讶的是它可以按我的意愿工作至):

char retazec[50];
char kategoria[50];

i = 0;
j = 0;
printf("%d\n", pocet_slov);
while (fgets(retazec, 50, otazky) != NULL) {
    switch(retazec[0]) {
    case '#':
        strcpy(kategoria, retazec);
        strcpy(slova[i-j].kategoria, retazec);
        j++;
        break;
    case '-':
        strcpy(slova[i-j].kategoria, kategoria);
        strcpy(slova[i-j].slovo, retazec);
        j++;
        break;
    case '*':
        strcpy(slova[i-j].napoveda, retazec);
        j++;
        break;
    }
    i++;
}

fclose(otazky);

for (i = 0; i < pocet_slov; i++) {
    putchar('\n');
    putchar('\n');
    printf("%s", slova[i].kategoria);
    printf("%s", slova[i].slovo);
    printf("%s", slova[i].napoveda);
}

输出:
#类别
-单词
*帮助猜词

#类别
-单词*帮助猜词

然后,如果它找到另一个类别,它会像这样:

# another category
- word
* help

# another category
- word
* help

于 2013-04-12T07:02:26.050 回答