c中的链表,意外结果

时间:2012-02-13 17:25:31

标签: c linked-list

我是编程新手,正在尝试学习链接列表。我决定通过编写一个简单的程序来试验链接列表,该程序将从文件中读取,一次一个字符,并将每个字符插入到链接列表中。然后我打印出链表。简单吧?好吧,也许不是,如果这是你第一次。我正在关注在线教程哦,如此仔细,但我的输出不是它应该是的。 (程序编译并运行时没有错误或警告。我正在使用代码块。)我得到两个数字,而不是获取任何字符,而这就是全部。

这是我写的代码:

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

typedef struct Tokens_read_in{
    char character;
    int number;
    char whichOne[5];
    struct Tokens_read_in* next;
}Tokens;

int main()
{

    //declare variables
    char c;

    //create a struct for the array that will hold the tokens
    Tokens* token_array;
    token_array = malloc(sizeof(Tokens));
    token_array->next = NULL;

    //open the input file
    FILE *ifp;  //input file pointer
    char *filename = "input.txt";
    ifp = fopen(filename, "r");

    if(!ifp){
        printf("Error in opening '%s' for reading!", filename);
        exit(0);
    }

    while(!feof(ifp)){

        //prepare to read in file one character at a time
        c = getc(ifp);

        //create a struct for the current token that is read in
        Tokens* current_token = token_array;

        //let the current_token point to the beginning of token_array
        current_token = token_array;

        //let the current_token point to the LAST of token_array
        while(current_token->next != NULL){
            current_token = current_token->next;
        }

        //create a node at the end of token_array
        current_token->next = malloc(sizeof(Tokens));

        //move the current_token to the last (new) of token_array
        current_token = current_token->next;
        if(current_token == NULL){
            printf("Out of memory");
            exit(0);
        }

        //plug character into current_token
        current_token->next = NULL;
        //letter
        if(isalpha(c)){
            printf("%c", c);
            current_token->character = c;
            strcpy(current_token->whichOne, "char");
        }
        //number
        else if(isdigit(c))
        {
            printf("%d", (int)c);
            current_token->number = (int)c;
            strcpy(current_token->whichOne, "num");
        }
        //space
        //this does not need to go into the token array
        else if (c == ' '){
            printf(" ");
        }
        //newline
        //this does not need to go into the token array
        else if (c == '\n'){
            printf("\n");
        }
        //anything else
        else if ((!isdigit(c) && !isalpha(c))){
            printf("%c", c);
            current_token->character = c;
            strcpy(current_token->whichOne, "char");
        }

        //now that the current_token is plugged into token_array, free current_token
        free(current_token);

    }//end while(!feof(ifp))

    //print the token_array
    Tokens* conductor;
    conductor = token_array;
    while(conductor != NULL){
        if(strcmp(conductor->whichOne, "num")){
            printf("%d ", conductor->number);
        }
        else if(strcmp(conductor->whichOne, "char")){
            printf("%c ", conductor->character);
        }
        conductor = conductor->next;
    }
    //done printing, so free conductor
    free(conductor);

    //done with program, so free token_array
    free(token_array);

    //close input file
    fclose(ifp);

    return 0;
}//end main

这是我正在使用的输入文件(名为input.txt):

<I don't know why every beginner program says hello world,
but hello world anyway.>

我非常感谢任何看过这个并指出我正确方向的人。

5 个答案:

答案 0 :(得分:5)

您不应在读​​取循环结束时释放current_token。这将导致问题,因为您正在释放链接列表中的节点的内存。

另外,作为附注,当给出表示数字的字符时,isdigit会成功,因此例如字符“1”。您应该仍然使用%c来打印出来,因为%d会为您提供字符“1”的ascii编号。

答案 1 :(得分:4)

您需要if (strcmp(a,b)==0)来测试是否相等。

答案 2 :(得分:1)

  • 您绝对不想free(current_token)
  • 如果要将char转换为int,则执行此操作的简单方法是:
    char c = '3';
    int i = c - '0';
    printf("As a char: %c\n", c); // Prints 3.
    printf("As an int: %d\n", i); // Prints 3.
  • 当您使用malloc数据时,该区域中可能存在随机数据。一旦使用memset对其进行malloc操作,就应该清除整个结构。
  • 如其他答案中所述,strcmp在匹配时返回0。这意味着您正在进行所需的比较。
  • 当字符是空格或换行符时,结构中的数据非常奇怪。这是因为数据以未确定状态开始。

如果您修复了上述错误(不包括memset),程序的输出更像您想要的。

答案 3 :(得分:1)

当两个字符串相等时,strcmp返回零

http://pubs.opengroup.org/onlinepubs/007904875/functions/strcmp.html

并且可能你想避免使用eof字符。

第99行中的

conductor = (token_array->next);

而不是

conductor = token_array;

答案 4 :(得分:0)

//now that the current_token is plugged into token_array, free current_token
        free(current_token);

    }//end while(!feof(ifp))

尝试评论对free(current_token);

的调用

malloc和free的工作是跟踪已分配的内存。当您调用free时,下一个malloc调用可能会向您发回您刚刚使用的相同内存地址。

此外

//create a struct for the current token that is read in
Tokens* current_token = token_array;

//let the current_token point to the beginning of token_array
current_token = token_array;

第二项任务是多余的。不是一个错误(还),但只是一个新程序员的注释。

另外,请告诉我们您收到的电话号码。获取数字而不是字符有时可能表示您正在输出ASCII代码而不是字符本身。