【问题标题】:fscanf() replacing my ADT nodes?fscanf() 替换我的 ADT 节点?
【发布时间】:2017-03-18 18:50:44
【问题描述】:

我正在编写一个函数来从文本文件中读取并逐字提取字符串并将它们存储到二叉搜索树中。该函数应忽略所有标点符号并丢弃重复的单词(仅增加单词频率)。

我现在对代码的问题是每次“while (fscanf(fp, "%s", line)!=EOF)" 运行时,我的 rootWord 都会被新读取的单词替换。我不知道 fscanf 怎么可能做到这一点。

typedef struct word * wordPtr;
typedef struct position * positionPtr;

typedef struct position
{
    int position;
    positionPtr nextPosition;
} Position;
typedef struct word
{
    char * word;
    unsigned freq;
    positionPtr firstPosition;
    wordPtr leftWord;
    wordPtr rightWord;
} Word;

typedef struct bstWord
{
    wordPtr rootWord;
    unsigned wordCount;
} BSTWord;

int BSTCreate(BSTWord* bst, char* fileName)
{
    FILE * fp = fopen(fileName,"r");
    char line[MAX_WORD_LEN + 1];
    int charCount = 0;
    char * token;
    char delimit[] = "\t\r\n\v\f,.-;:\"\' ";    

    while (fscanf(fp, "%s", line)!=EOF)
    {
        wordPtr prev = NULL, curr = bst->rootWord;          
        wordPtr newWord;
        positionPtr newPosition;
        int lessThen;
        int status = 1;                         
        token = strtok(line, delimit);          
        charCount = charCount + 1;          

        while(curr!=NULL)
        {
            prev = curr;

            if(strcmp(token, curr->word)<0)
            {
                printf("\nless");
                lessThen = 1;
                curr = curr->leftWord;
                status = 1;
            }
            else if(strcmp(token, curr->word)>0)
            {
                printf("\nmore");
                lessThen = 0;
                curr = curr->rightWord;
                status = 1;
            }
            else if(strcmp(token, curr->word)==0) //If word is already in tree, add freq + update position
            {

                if ( ( newPosition = malloc( sizeof( Position ) ) ) == NULL )
                    return FAILURE;

                newPosition->position = charCount;
                newPosition->nextPosition = NULL;

                positionPtr prevPosition = NULL, currPosition = curr->firstPosition;
                while(currPosition!=NULL)
                {
                    prevPosition = currPosition;
                    currPosition = currPosition->nextPosition;
                }
                prevPosition->nextPosition = newPosition;
                status = 0;
                curr = NULL;
                break;
            }

        }
        if(status == 1)
        {
            if ( ( newWord = malloc( sizeof( Word ) ) ) == NULL )
                return FAILURE;

            if ( ( newPosition = malloc( sizeof( Position ) ) ) == NULL )
                return FAILURE;

            newPosition->position = charCount;

            newWord->word = token;
            newWord->freq = 1;
            newWord->firstPosition = newPosition;
            newWord->leftWord = NULL;
            newWord->rightWord = NULL;

            if(bst->rootWord == NULL)
                bst->rootWord = newWord;
            else
            {
                if(lessThen)
                {   
                    prev->leftWord = newWord;
                }
                else
                {   
                    prev->rightWord = newWord;
                }
            }           
        }
        bst->wordCount++;
    }
    fclose(fp);        
    free(fp);

    return SUCCESS;
}

【问题讨论】:

  • 你知道strtok() 没有分配一个新的缓冲区,而是返回一个指向它传递的缓冲区的指针?
  • 我不知道,我去查一下,谢谢。

标签: c


【解决方案1】:
newWord->word = token;

每个标记都指向您分配的相同内存:

char line[MAX_WORD_LEN + 1];

您需要分配额外的内存并将字符串复制到那里:

newword->word = malloc(strlen(token) + 1); 
strcpy(newword->word, token);

【讨论】:

  • 谢谢!没有意识到这一点。
猜你喜欢
  • 1970-01-01
  • 2020-11-05
  • 1970-01-01
  • 1970-01-01
  • 2014-03-04
  • 2021-12-30
  • 2021-10-18
  • 2014-08-27
  • 1970-01-01
相关资源
最近更新 更多