Thread: Passing Wrong datas

  1. #1
    Registered User
    Join Date
    May 2013
    Posts
    59

    Passing Wrong datas

    I've found that the data passed to my mxWeight function is wrong but i cant seem to detect where it is. And i the totalweight keeps exceeding the limit. Please help, thanks.


    Code:
    /* Main */
    
    int main()
    {
        int maxCnr;
        int file = 0;
        double maxWeight;
        char filename[50]; 
        char choice;
        FILE *input;
        List *list = lst_new();
    
    
            
        printf("********************** WELCOME TO SHIPMANAGER **********************\n\n");
        
        printf("Please enter the maximum number of containers the ship can carry: ");
        scanf("%i", &maxCnr);
        
        printf("\nPlease enter the maximum weight the ship can carry: ");
        scanf("%lf", &maxWeight);
        
        do {
            printf("\nEnter the filename (.txt): ");
            scanf("%s", &filename);
            
            input = fopen(filename, "r");
            if (input == NULL)
            {
                file = 0;
                printf("File does not exist. \n");
            }
            else 
            {
                printf("File located.\n");
                file = 1;
            }
        }while(file == 0);
        
        readContainer(list,filename);
        
        
        mxCnr(&list, maxCnr);
        
        
        mxWeight(&list, maxWeight); 
        
        
        printContainers(list);
        
    }
    /* ensure that the container does not exceed the maximum number */
    
    void mxCnr(List **list, int mCnr)
    {
        Container *tmpContainer;
        List *max = lst_new();
        int i = 0;
        
        
       for (tmpContainer = lst_first(*list); i<mCnr; tmpContainer = lst_next(*list))
        {
            Node *previous = NULL;
            Node *current = max->head;
                
            if (max->size == 0)
                lst_add(max, tmpContainer);
            
            else
            {               
                Node *newNode = node_new(tmpContainer, NULL);
                current = max->head;
                
                
                while (node_getNext(current) != NULL)
                {
                    previous = current;
                    current = node_getNext(current);
                }
            
            if (previous == NULL)
            {
                node_setNext(newNode, max->head);
                max->head = newNode;    
            }
            
            else
            {
                max->tail->next = newNode;
                max->tail = newNode;
            }
            
            max->size++;
            
            }
            
            i++;
        }
        
        lst_delete(*list);
        
        *list = max;
        
    }
    
    
    /* function to calculate the total weight and to ensure that the weight does not exceed the maximum weight */
    
    void mxWeight(List **list, double mWeight)
    {
        Container *tmpContainer;
        List *maxW = lst_new();
        double totalweight= 0;
        printf("maxweight :%lf ", mWeight);
        
       for (tmpContainer = lst_first(*list); totalweight<=mWeight; tmpContainer = lst_next(*list))
        {
            Node *current = maxW->head;
            Node *previous = NULL;
            printf("maxweight :%lf ", mWeight);
            
            if (maxW->size == 0)
            {
                lst_add(maxW, tmpContainer);
                
            }
            else
            {               
                Node *newNode = node_new(tmpContainer, NULL);
                current = maxW->head;
                              
                            
                while (node_getNext(current) != NULL && totalweight <= mWeight)
                {
                    previous = current;
                    current = node_getNext(current);    
                    totalweight = totalweight + cnr_getWeight(node_getData(current));    
                    printf("%lf ", cnr_getWeight(node_getData(current)));              
                }
                            
                if (previous == NULL)
                {
                    node_setNext(newNode, maxW->head);
                    maxW->head = newNode;                                           
                }
            
                else 
                {
                    maxW->tail->next = newNode;
                    maxW->tail = newNode;
                }
                
                
                maxW->size++;
            
            
            }
            
        }
        printf("Total weight: %lf", totalweight);
        lst_delete(*list);
        
        *list = maxW;
        
    }

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by Alexius Lim View Post
    I've found that the data passed to my mxWeight function is wrong
    How wrong?

    What you enter? what you expect to get in the function? What you are really getting?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Registered User
    Join Date
    May 2013
    Posts
    59
    lets say i enter the following: maximum weight number of containers the ship can carry: 10 maximum weight:5 filename: containerlist.txt
    Output:
    Code:
    Weight: 1.82 Shipping Price:2537.76  <---- total exceed 5
    Weight: 2.98 Shipping Price:5526.86
    Weight: 6.22 Shipping Price:8444.84
    Weight: 6.77 Shipping Price:4698.15
    
    Total weight: 5.96 <----- Wrong


    I tried to put a print my weight below
    totalweight = totalweight + cnr_getWeight(node_getData(current));
    to see what value im getting and it turns out to be something else 2.98 and 2.9 which are some other value from my txt file.

    I've check up with my lecturer and he says my problem might be the data that is passed to my mxWeight function might be wrong.

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    I do not see a code for the output you are showing.

    What I see - mxCnr modifies the list before passing it to mxWeight

    So try to comment it out and see it your mxWeight function is working correctly with original data.
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    More complete info may be useful. A full program listing, including readContainer and printContainer, and also the input file you use would help us immensely.

    Also, you leak a file handle in main. You use input to check if the file exists, but then only pass the file name to readContainer (presumably it opens and closes the file). You can pass the open file handle, and close it in main when done, which will help fix the leak and simplify main a little bit. Try the following:
    Code:
    do {
        print "Enter file name"
        read filename
        input = fopen
        if (input == NULL) {
            perror("fopen");  // a file may fail to open for many reasons (not just "doesn't exist"), perror will tell you the actual reason
        }
    } while (input == NULL);
    readContainer(list, input);  // passing in the open file handle
    fclose(input);  // done with it, close it
    ...
    void readContainer(List *list, FILE *input)
    {
        ...
    }

  6. #6
    Registered User
    Join Date
    May 2013
    Posts
    59
    Quote Originally Posted by vart View Post
    I do not see a code for the output you are showing.

    What I see - mxCnr modifies the list before passing it to mxWeight
    my output is actually in another function. i did not put it up as it might be too long.

    Code:
    void printContainers(List *list)
    {
        char string[100];
        
        Container *tempContainer;
        
        printf("\nContainer in list: %d \n", list->size);
        
        for (tempContainer = lst_first(list); tempContainer != NULL; tempContainer = lst_next(list))
            printf("%s\n", cnr_toString(tempContainer, string));
        
    
    }
    
    void readContainer(List *list, char filename[50])
    {
    
    
    	Container *tempCnr;
    	FILE *input;
    	
    	input = fopen(filename, "r");
    	if (input == NULL)
    	{
    		printf("Error opening %s for reading", filename);
    		exit(1);
    	}
    	
    	tempCnr = cnr_read(input);
    	
    	while (tempCnr != NULL)
    	{
    		lst_add(list, tempCnr);
    		tempCnr = cnr_read(input);
    	}
    	
    	fclose(input);
    }
    
    
    Container *cnr_read(FILE *input)
    {
    	
    	int numRead;
    	
    	Container *contain = (Container *)malloc(sizeof(Container)); /* assign dynamic memory for contain */
    	
    	if (contain !=NULL) 
    	{
    		char cnr_id[10];
    		
    				
    		numRead = fscanf(input, "%s %lf %lf", cnr_id, &(contain->weight), &(contain->shippingPrice));
    	
    		if (numRead != 3) /* 3 type of value id, weight and shipping price */
    		{
    			free(contain);
    			contain = NULL;
    		}
    		else
    		{
    			contain->id = (char *) malloc((strlen(cnr_id)+1)* sizeof(char));
    			if (contain->id != NULL)
    			{
    				strcpy(contain->id, cnr_id);
    				
    			}
    		}
    	}
    		
    	return contain;
    }
    Last edited by Alexius Lim; 08-15-2013 at 09:56 AM.

  7. #7
    Registered User
    Join Date
    May 2013
    Posts
    59
    Quote Originally Posted by anduril462 View Post
    and also the input file you use would help us immensely.
    the input file as in the text file?

    this is just the top part of the text file.

    Code:
    1G7EL416 1.82 2537.76
    GXOW3DW8 2.98 5526.86
    40RWPU10 6.22 8444.84
    W610BG43 6.77 4698.15
    GN27I0DE 8.47 4983.11
    63A0X03J 4.79 8286.78
    07EYWJ25 7.71 14175.91
    IP916ZL4 2.56 1539.92
    03SS64HM 8.53 16321.52
    6G99XRY6 1.76 1319.24
    3OMFI1S6 6.76 11817.70
    32Z501WT 2.49 2508.01
    6AI89Q38 9.20 10842.01
    Z355L2UZ 1.48 1045.76
    T9X95O3B 8.03 5873.83
    4A688BKW 8.52 12385.06
    B41IKR52 6.58 12447.98
    S1NZ9Y6L 8.92 16928.26
    641NCH2Q 8.37 9553.01
    3J2T70N8 2.08 1518.28
    374KH1S9 2.75 2203.18

  8. #8
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    A full program listing, including readContainer and printContainer. I can't compile or debug without a full listing. Compiling with max warnings is an easy way to catch small mistakes that may cause undesired behavior in your program. Being able to step through line by line, or putting a watch on a value that seems to change when you don't expect it would be very useful here. Please provide everything we need to compile and debug this program. Definitions of List and Node types, list functions, node functions, etc. Everything.

    EDIT: If it's like 1000-2000 lines, maybe reconsider, but I imagine this is more in the 500 range, which is fine.
    Last edited by anduril462; 08-15-2013 at 10:28 AM.

  9. #9
    Registered User
    Join Date
    May 2013
    Posts
    59
    I think it will be easier if i just upload my files.
    Attached Files Attached Files

  10. #10
    Registered User
    Join Date
    May 2013
    Posts
    59
    Ignore the commented parts
    Attached Files Attached Files

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Sorry for the delay, a few minor notes to start:
    Code:
    gcc -Wall -o ship container.o node.o shipmanager.o
    shipmanager.o: In function `addContainer':
    /usr/local/google/home/cagarvin/sandbox/cprogramming/ship/shipmanager.c:331: undefined reference to `getche'
    getche is specific to conio.h, which is an outdated and non-standard header. Don't #include the conio.h header, and prefer getchar() to get a single character from the user. Fixing that gives:
    Code:
    gcc -Wall -ggdb3 -std=c99 -c shipmanager.c
    shipmanager.c: In function ‘main’:
    shipmanager.c:95:3: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[50]’ [-Wformat]
    shipmanager.c:80:7: warning: unused variable ‘choice’ [-Wunused-variable]
    You don't need an & when using scanf with a char array. The name of the array is a pointer to the first element. Just do scanf("%s", filename). Drop the unused variable.

    It's going to take me a little while to actually figure out what's wrong. I'll get back to you later.

  12. #12
    Registered User
    Join Date
    May 2013
    Posts
    59
    ok thanks a bunch!

  13. #13
    Registered User
    Join Date
    May 2013
    Posts
    59
    Quote Originally Posted by vart View Post
    So try to comment it out and see it your mxWeight function is working correctly with original data.
    Its not but i do not know where i made the mistake

  14. #14
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Code:
    double totalweight = 0;
    
    for (tmpContainer = lst_first(*list); totalweight<=mWeight; tmpContainer = lst_next(*list))
    {
        ...
        // if you print totalweight here, you'll see it's non-zero, which is not right -- initialize it to zero here
        while (node_getNext(current) != NULL && totalweight <= mWeight)
        {
            previous = current;
            current = node_getNext(current);    
            totalweight = totalweight + cnr_getWeight(node_getData(current));    
            printf("%lf ", cnr_getWeight(node_getData(current)));              
        }
    You initialize totalweight to 0 at the beginning of the function. Your for loop iterates through your big list of containers, adding them to your small list (maxW). Each time through that for loop (except the first time), you run that while loop, adding all the weights in maxW to totalweight. But you never reset totalweight, so you're counting containers more than once. For example, if your big list

    The second problem is that your loop check checks if totalweight is currently less than mWeight. But inside the loop, you blindly add to totalweight and to the maxW list, even if the new totalweight will exceed the maximum. You need an if-check inside that loop:
    Code:
    while (not at end of list && totalweight <= maxW)
        if (totalweight + weight of current node <= maxW)
            add current node to maxW list and add it's weight to total weight

  15. #15
    Registered User
    Join Date
    May 2013
    Posts
    59
    ok i'll give it a try

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 12
    Last Post: 08-15-2013, 03:00 AM
  2. How many datas when I send datas each time?
    By leetow2003 in forum Networking/Device Communication
    Replies: 1
    Last Post: 03-12-2012, 11:18 AM
  3. Calling datas from another form?
    By Aga^^ in forum C# Programming
    Replies: 2
    Last Post: 02-06-2009, 02:17 AM
  4. Replies: 4
    Last Post: 08-07-2007, 02:55 PM
  5. Passing variables by pointers...what am I doing wrong?
    By Shadow12345 in forum C++ Programming
    Replies: 2
    Last Post: 06-07-2002, 02:10 PM

Tags for this Thread