Thread: Calculating Olympic medals

  1. #1
    Registered User
    Join Date
    Apr 2018
    Posts
    6

    Calculating Olympic medals

    Code:
     
    
    int addcountry(struct medals *as, char *name){
        as->country = malloc(strlen(name)+1);
        if(strcpy(as->country, name) == NULL){
            return 0;
        }
        as->gold = 0;
        as->silver = 0;
        as->bronze = 0;
        return 1;
    }
        
    void updatemedals(struct medals *as, int size, char *name, int first, int second, int third){
        int i;
        for(i = 0; i < size; i++){
            if(strcmp(as[i].country,name)==0){
            as[i].gold += first;
            as[i].silver += second;
            as[i].bronze += third;
            }
            else{continue;}
        }
    }
    void printtable(struct medals *as){
    
    
        printf("%s %d %d %d\n",as->country, as->gold, as->silver, as->bronze);
        
        
    }
    
    
    int main(){
    
    
        struct medals a1;
        char arrays[20];
        char *info = arrays;
        char list[1028];
        int g, s, b;
        int size = 0;
        printf("Enter country and medals");
        char firstletter;
        while(scanf(" %s", list) > 0){
            if(list[0] == 'A'){
                sscanf(list, "%s, %s", &firstletter, info);
                addcountry(&a1, info);
                size++;
            }
            else if(list[0] == 'M'){
                sscanf(list, "%s, %s, %d, %d, %d", &firstletter, info, &g, &s, &b);
    
    
                updatemedals(&a1, size, info, g, s, b);
            }
            else if(list[0] == 'L'){
                    printtable(&a1);
            }
    
    
        }
        return 0;
    }

    Im doing program that calculates countries medals. First input is for example 'A Canada' which creates new field. And second input is for example 'Canada 1 1 2'. I have probably some mistakes here and I cant find them. My main function is pretty messy so if someone could give some help how to fix main function it would be great.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > if(strcpy(as->country, name) == NULL)
    strcpy never returns anything other than the destination pointer.
    If you want to check something, then check as->country is not NULL before doing anything else.

    For your main, then
    1. Remove all variables which you don't need.
    2. Give the remaining ones better names. char arrays[] is meaningless, a1 is also non-descript.

    > while(scanf(" %s", list) > 0)
    This will never read in a line containing spaces.
    Use
    while ( fgets(list,sizeof(list),stdin) != NULL )

    > sscanf(list, "%s, %s, %d, %d, %d", &firstletter, info, &g, &s, &b);
    Your example input of "Canada 1 1 2" doesn't contain commas, so your sscanf will fail.

    Another gotcha is using "%s" with a char variable, which is wrong even for just a single character.
    You can use "%*s" if you just want to skip over a word without having to worry about storing it anywhere.

    Another point on variables would be keep scope to a minimum.
    Code:
            
    else if(list[0] == 'M'){
        int g, s, b;
        if ( sscanf(list, "%*s %s %d %d %d", info, &g, &s, &b) == 4 ) {
        } else {
            // error
        }
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Apr 2018
    Posts
    6
    Code:
    while(fgets(list, sizeof(list), stdin) != NULL){
    		if(list[0] == 'A'){
    			sscanf(list, "%s %*s", &firstletter, info);
    			addcountry(&a1, info);
    			size++;
    		}
    		else if(list[0] == 'M'){
    			int g, s, b;
    			if (sscanf(list, "%s %*s %s %d %d %d", &firstletter, info, &g, &s, &b) ==4){updatemedals(&a1, size, info, g, s, b);}
    			else{printf("Failed!");}
    		}
    		else if(list[0] == 'L'){
    				printtable(&a1);
    		}
    
    
    	}
    	return 0;
    }
    I tried to fix but it goes to Segmentation fault and it gives one warning " sscanf(list, "%s %*s", &firstletter, info) ”info” may be used uninitialized in this function -Wmaybe-uninitialized

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    1. Why are you ignoring the second string, and not the first.
    2. If you're ignoring a field, then you DON'T need variable to store it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Apr 2018
    Posts
    6
    Users input will be for example: ' A Canada ' (creating new field)
    next input: 'M Canada 1 0 0', which will update current medal situation.
    I'm beginner so I'm little uncertain what are you saying, but I dont want to ignore any field but I try to do the process in parts; first create then update.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    I showed you this
    > if ( sscanf(list, "%*s %s %d %d %d", info, &g, &s, &b) == 4 )

    You did this
    > if (sscanf(list, "%s %*s %s %d %d %d", &firstletter, info, &g, &s, &b) ==4)

    You're unsure, but you make random edits and then wonder why it all goes wrong.

    You already processed the first letter with things like
    > else if(list[0] == 'M')
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Apr 2018
    Posts
    6
    Thanks!
    I have also one problem; when I input more than one for example, "A Canada" "A China" "M Canada 1 0 0" "M China 2 1 1", I get some strange output: "Canada 1 0 0" "1962936908 543780207 540024889"
    I modified my printfunction to:
    Code:
    for(int i=0; i<size; i++){
            printf("%s %d %d %d\n",as[i].country, as[i].gold, as[i].silver, as[i].bronze);
        }

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    You need to make a1 an array.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Apr 2018
    Posts
    6
    How should I do it? I tried few ways but cant do it properly

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    a1 [5]
    size = 5

    Post what you tried.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Registered User
    Join Date
    Apr 2018
    Posts
    6
    I did struct medals a1[20] and removed & -signs from function calls

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    The whole code.

    Not a description of what you had for breakfast.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 05-10-2015, 06:57 AM
  2. New Olympic games?
    By cpjust in forum General Discussions
    Replies: 14
    Last Post: 02-22-2010, 12:23 PM
  3. calculating the mean
    By bartleby84 in forum C Programming
    Replies: 9
    Last Post: 08-27-2007, 11:47 AM
  4. Beijing 2008 Olympic Mascots
    By Hermitsky in forum A Brief History of Cprogramming.com
    Replies: 9
    Last Post: 11-15-2005, 01:53 PM

Tags for this Thread