使用C创建用户名和Balance的列表

时间:2014-06-13 18:28:52

标签: c list pointers

我正在尝试创建用户名和余额列表。代码编译完全正常,但有一个我无法弄清楚的逻辑错误。 基本上代码应该采用时间戳,用户名和余额。检查每个输入的一些条件。在文件末尾,计算机应打印出相关用户名的最新余额。

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

//function declaration
int checkTimeStamp(int currentTS, int prevTS);
int checkBalance(float currentBal, float prevBal);

//Nodes for each List
struct node
{
    char userName[31];
    float balance;
    struct node *next;
};

int main()
{
    //Float and int variables
    float bal;
    int timeStamp;
    int listCount = 0; //Keep Track of the number of nodes
    int iEach = 0;
    int check = 0; //user for validating input string
    int prevTS = 0;
    int prevBal = 0;
    int checkBal;
    int checkTS;

    //String variables
    char userID[31];
    char input[130];


    //Node variables
    struct node root = { "", 0, NULL};// declare and initialize the first structure
    struct node* freeNode = NULL;// declare a pointer and initialize it null. use for freeing memory later
    struct node* pNode = &root;// declare a pointer and initialize it to point to the first structure

    while( fgets(input, 130, stdin) )
    {
        check = sscanf(input, "%d %s %f" , &timeStamp, userID, &bal); //checking if the user has entered the right values
        //printf("%d\n", check);

        if( check == 0 ) //checking if timestamp was integer
        {
            printf("Invalid time\n");
        }
        else if( check == 2 ) //checking if balance was float
        {
            printf("Illegal balance\n");
            prevTS = timeStamp;
        }
        else //if check >= 3
        {
            //pNode->next = malloc ( sizeof( struct node));// allocate memory for the next structure
            checkBal = checkBalance(bal, prevBal);
            checkTS = checkTimeStamp(timeStamp, prevTS);
            if(checkTS == 1)
            {
                printf("Non-monotonic timestamps\n");  
            }
            else if( checkBal == -1 )
            {
                printf("Debit!!!\n");  
                prevTS = timeStamp;
                listCount++;
                strcpy(pNode->userName,userID); // use the pointer to assign the userID
                pNode->balance = bal;
                pNode->next = malloc ( sizeof ( struct node));// allocate memory for the next structure

            }
            else if( checkBal == 1 )
            {
                printf("Suspiciously large balance change\n");
                prevTS = timeStamp;
                prevBal = bal;
                listCount++;
                strcpy(pNode->userName,userID); // use the pointer to assign the userID
                pNode->balance = bal;
                pNode->next = malloc ( sizeof ( struct node));// allocate memory for the next structure
            }
            else if( checkBal == 2 && checkTS == 2)
            {
                printf("Ok\n");
                prevTS = timeStamp;
                prevBal = bal;
                listCount++;
                strcpy(pNode->userName,userID); // use the pointer to assign the userID
                pNode->balance = bal;
                pNode->next = malloc ( sizeof ( struct node));// allocate memory for the next structure
            }

        }

    }
    pNode = &root; // set the pointer to the original structure root
    for ( iEach = 0; iEach < listCount; iEach++) // loop through each structure. ilistCount holds the number of structures
    {
        printf("Location number %d is : (%s,%.2f)\n", iEach + 1, pNode->userName, pNode->balance);
        pNode = pNode->next; // set the pointer to the next structure

    }

    pNode = root.next; // set the pointer to the first allocated structure
    for ( iEach = 1; iEach < listCount; iEach++) // loop through each structure
        //start with 1 as the first structure was not allocate and does not need to be freed. ilistCount holds the number of structures
    {
        freeNode = pNode->next; // set the free pointer to the next structure
        free ( pNode); // free the memory for the structure
        pNode = freeNode; // point to the free pointer
    }

}


//Functions
int checkTimeStamp(int currentTS, int prevTS)
{
    if( prevTS >= currentTS)
    {
        return 1;
    }
    else
    {
        return 2;  
    }  
}


int checkBalance(float currentBal, float prevBal)
{
    if( abs(currentBal - prevBal) >= 1000)
    {
        return 1;  
    }
    else if ( currentBal < 0)
    {
        return -1; 
    }
    else
    {
        return 2;  
    }
}

当输入为:

Testing 234 234.153
1235 Mega0123test -x-0.5
3600 godzilla 300
36000 godzilla 299
36001 godzilla 2000
36002 godzilla 0
36003 godzilla -10
36004 godzilla1 10
36005 godzilla2 10
36006 godzilla3 10 
1000 innocent 69
^D

输出应该是:

Illegal balance
Ok
Ok
Suspiciously large balance change
Suspiciously large balance change
Debit!!!
Ok
Ok
Ok
Non-monotonic timestamps
Invalid time
Non-monotonic timestamps
godzilla 0
godzilla -10
godzilla1 10
godzilla2 10
godzilla3 10 

但是我得到了

Illegal balance
Ok
Ok
Suspiciously large balance change
Suspiciously large balance change
Debit!!!
Ok
Ok
Ok
Non-monotonic timestamps
Invalid time
Non-monotonic timestamps
Location number 1 is : (godzilla3,10.00)
Location number 2 is : (,0.00)
Segmentation fault (core dumped)

2 个答案:

答案 0 :(得分:1)

这不是逻辑错误(至少不是你的意思)。消息

Segmentation fault (core dumped)

表示程序访问了一些它不应该拥有的内存,导致操作系统将其终止。您应该在调试器或内存检查器中加载程序,然后逐步查看程序,查找非法访问的位置。

在Linux上,一个好的调试器是 gdb ,GNU Debugger。我同样推荐的内存检查器是 valgrind (和朋友)。这些都不是默认安装的,但可以通过例如

获得
sudo apt-get install gdb valgrind

解释如何使用这些将是一个非常长的答案,但那里有一些很好的教程,只需使用搜索引擎。

答案 1 :(得分:0)

在您的第一个while循环中,您永远不会更改pNode,因此始终指向root

没有任何malloc&lt; d>节点被初始化。

后面的循环迭代到未初始化的内存中。

@ user3121023在对问题的评论中给出解决方案。