0

Everyone! I was given list of data with countries and number of enrollees male and female in the table, my task is to read in and sort the sum in descending order.

Have no problems with reading in, but I have problems with sorting as you may guess.

On the output I have only 2 countries instead of 158.

Here is my code

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

typedef struct _person_count {
    char country[80];
    long females;
    long males;
    struct _person_count *link;
} person_count;

void printList(person_count *node) {
    if (node != NULL) {
        printf("%25s %10d %10d  %10d \n", node->country, node->females,
            node->males, node->males + node->females);
        printList(node->link);
   }
}

int main() {
    FILE *infile;
    infile = fopen("file.txt", "r");
    if (infile == NULL) {
        printf("Problem opening files.");
        return 1;
    }

    person_count *first = NULL;
    person_count *curr = NULL;
    person_count *prev = NULL;
    person_count *a = NULL;

    do {
        person_count *newNode = malloc(sizeof(person_count));
        fscanf(infile, "%s %ld %ld", &newNode->country, &newNode->females,
            &newNode->males);

        newNode->link = NULL;

        if (first == NULL) {
            first = newNode;
        } else {
            prev->link = newNode;
        };
        curr = first;

        if ((newNode->females + newNode->males)
                > (first->females + first->males)) {
            newNode->link = first;
            first = newNode;
        } else {
            do {
                if (curr->link == NULL) {
                    curr->link = newNode;
                    printf("a\n");
                    break;
                }
                if ((newNode->females + newNode->males)
                        < (curr->link->females + curr->link->males)) {
                    curr = curr->link;
                    printf("b\n");
                    continue;
                } else {
                    newNode->link = curr->link;
                    curr->link = newNode;
                    printf("c\n");
                    break;
                }
            } while (curr->link->link != NULL);
        }
        prev = newNode;

    } while (!feof(infile));
    printList(first);

    printf("\n\n\nnew\n\n\n");

    printList(curr);

    return 0;
}

It return this output

China   47803801   52828124   100631925 
India   38383177   51078616    89461793 
USA   12008749   12423185    24431934 
Vietnam    4827551    5111768     9939319 
Yemen     466693     988523     1455216 
Zambia     183200     225771      408971 

new

Yemen     466693     988523     1455216 
Zambia     183200     225771      408971 

Could you help?

Thank you in advance!

dragosht
  • 3,237
  • 2
  • 23
  • 32
Topisan
  • 9
  • 2
  • "Problem opening files" is *not* a useful error message. `char *path = "file.txt"; infile = fopen( path, "r"); if( infile == NULL ) { perror(path); return 1; }` – William Pursell Nov 10 '15 at 06:57
  • 3
    The best way to learn this kind of list work is to draw it on paper. Draw arrows from each pointer to the blocks as you move through the data. Your error will reveal itself. – john elemans Nov 10 '15 at 07:13
  • Debugger.............................DCV – Martin James Nov 10 '15 at 10:52

2 Answers2

0

Well your code printList(curr); actually prints where the curr points to, and also prints all the next elemets after it, but curr itself does not point to the head of the list. And printList(first); already prints the sorted list.

0

It is a bit unclear what output you are looking for. The final two calls to printList with (first) and (curr) have nothing in between them aside from a printf statement. If your intent is not to have only 2 line when printing curr, then you need to have curr point to the starting node of interest. Or as mentioned in the other answer, you can set both to first and for some reason that escapes me at the moment, print the list twice in succession similar to:

                China   47803801   52828124   100631925
                India   38383177   51078616    89461793
                  USA   12008749   12423185    24431934
              Vietnam    4827551    5111768     9939319
                Yemen     466693     988523     1455216
               Zambia     183200     225771      408971
new
                China   47803801   52828124   100631925
                India   38383177   51078616    89461793
                  USA   12008749   12423185    24431934
              Vietnam    4827551    5111768     9939319
                Yemen     466693     988523     1455216
               Zambia     183200     225771      408971

There is a problem with your read loop that will bite you sooner or later. You will want to see Why is “while ( !feof (file) )” always wrong? With a quick change, you can easily read with a for loop, e.g. for(;;) { and then simply `break when you have reached the end of data:

for (;;) {

    person_count *newNode = calloc(1, sizeof(person_count));
    if (fscanf(infile, "%s %ld %ld", newNode->country, 
        &newNode->females, &newNode->males) != 3)
        break;

    newNode->link = NULL;
    ...

Please provide additional clarification on what you expect to print after you printList (first) and I'll be happy to help further.

Community
  • 1
  • 1
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85