字符串以某种方式变异

时间:2014-02-03 00:53:21

标签: c data-structures string

我正在开发一个小程序,它有一个很小的逻辑错误,我似乎无法追查。它跟踪此表单的记录输入:

time userID weight

它搜索所有先前记录的链接列表,以查找userID与当前userID匹配的最新记录。然后比较时间和重量并计算重量的变化率。如果重量突然改变,则打印"suspicious weight change"。如果不匹配且输入有效,则只需将新记录添加到列表中。

我有它的工作,除非将userID添加到列表中,它似乎覆盖了所有以前的userID。因此,即使输入具有唯一userID的新记录,它也会找到匹配项,因为所有ID都是相同的。

我只需要第二双眼睛来帮助发现这种情况发生在哪里,我是C的新手,所以这可能是一些新手的错误。但是在试图找到它的8小时后,我迫切需要一些帮助!

debugging, after each input I print the list

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

#define DELIM " "                   /* the delimiter */
#define MAX_CHANGE (10.0/86400.0)   /* 10kg/day */

/* seconds in a day is 24 hours * 60 minutes * 60 seconds */

/* return 0 if the passed strings don't math, 1 otherwise */

/* defines the structure of Node */
struct Node
{
    char * id;
    float weight;
    int time;
    struct Node * next;
} *head, *p, *t, *last;

/* Constructor which returns a pointer to a new node*/

struct Node *newNode(int *time, char * id, float *w)
{
    /*note malloc returns a pointer */
    struct Node *r = (struct Node *)malloc( sizeof(struct Node) );

    r->time = *time;
    r->id = id;
    r->weight = *w;
    r->next = NULL;
    return r;
}


/* prints the list starting with head */
printList(struct Node * head)
{
    while(head != NULL)
    {
        printf("%d %s %f\n",head->time,head->id,head->weight);
        head = head->next;
    }
}


main()
{
    char line[1024];
    int lasttime = 0;
    int success;
    int timestamp;
    int duration;
    char userID[1000] = "";
    char *token;
    char temp[1000];
    float weight;
    float lastweight;
    float change;
    float changePerTime;

    head = (struct Node*)malloc(sizeof(struct Node));
    head->id = "";
    head->weight = 0.0;
    head->time = 0;
    head->next = NULL;
    last = head;

    /*FILE * f = fopen("C:\\Users\\Chris\\Documents\\School\\York\\Computer Science\\2031 Software Tools\\Labs\\lab3\\testcases\\06.in","r"); */
    /*  last points to the last node in the list
     head is always the same node
     p is used to travers the list
     t is a pointer the most recent occurrense of a user record
     */

    while (fgets(line,1024,stdin) != NULL)
    {
        userID[0] ='\0'; // resets userID
        token = strtok(line, DELIM);
        success = sscanf(token,"%d",&timestamp);

        if (success < 1 || timestamp == 0)
        {
            printf("Invalid time\n");
            continue;
        }

        while((token = strtok(NULL,DELIM) ) != NULL && token[0] != '.' && ! isdigit(token[0]) )
        {
            strcpy(temp,token); //
            strcat(temp,DELIM ); // adds space between each token
            strcat(userID, temp); // src temp must be a const string, not a pointer
            temp[0] = '\0';
        }

        userID[strlen(userID)-1] = '\0'; //erases the tailing space.

        if(strlen(userID) > 179 || !strlen(userID) )
        {
            printf("Illegal userID\n");
            continue;
        }

        else if(token == NULL || sscanf(token,"%f", &weight) < 1 || weight < 30.0 || weight > 300.0)
        {
            printf("Illegal weight\n");
            continue;
        }

        else if (lasttime >= timestamp)
        {
            printf("Nonmonotonic timestamps\n");
            continue;
        }

        else
        {
            /* sets t to last found user record and sets "last" to the last record*/
            for(p = head; p != NULL; p = p->next)
            {
                if(strcmp(userID,p->id) == 0)
                {
                    t=p;
                }
                last = p; // set last to last p.
            }

            if(t == NULL)
                printf("OK newuser\n");

            else if(t != NULL)
            {
                duration = timestamp - t->time;
                change = weight - t->weight;
                changePerTime = change / duration;

                if(changePerTime < -MAX_CHANGE || changePerTime > MAX_CHANGE)
                    printf("Suspiciously large weight change\n");
                else
                    printf("OK\n");
            }

            /* adds node to end of list */
            last->next = newNode(&timestamp,userID,&weight);
            printList(head);
        }       
    }

    //fclose(f);
}

1 个答案:

答案 0 :(得分:1)

我可以通过将newNode更改为:

来解决覆盖问题
struct Node *newNode(int *time, char * id, float *w)

{   /*note malloc returns a pointer */

    struct Node *r = (struct Node *)malloc( sizeof(struct Node) );

    r->time = *time;
    r->id = strdup(id);
    r->weight = *w;

    r->next = NULL;

return r;   

}

请注意添加对strdup的调用。