Thread: Question on file access and sorting

  1. #1
    Registered User
    Join Date
    Feb 2010
    Posts
    19

    Question on file access and sorting

    Hi guys
    I have been studying C on my own and want to access the contents of a file for the purpose of sorting them. I'm using 'bubble sort' because it seems a simple way to do content sorting. Anyway, my code compiles and runs but fails to print on screen the file content. Here is my code:

    Code:
    
    /* read, sort and display customer's id and balances */
    
       #include <stdio.h>
       #include <stdlib.h>
       #define MAX_CUSTOMERS 100
       
       struct custRec
       {
       	int ID;
       	float Bal;
       };
       
      /* prototypes of functions */
      int readInput(struct custRec *);
      void sortData(struct custRec *, int);
      void printRecords(struct custRec*, int);
    
      int main()
      {
      	int noOfRecords;
      	struct custRec custs[MAX_CUSTOMERS];
      	/* read the input */
      	noOfRecords = readInput(custs);
      	/* print the initial values */
      	printf("Before sorting\n");	
      	printRecords(custs,noOfRecords);
      	/* sort the array */
      	sortData(custs,noOfRecords);
      	/* print the sorted values */
      	printf("Ater sorting\n");
      	printRecords(custs,noOfRecords);
      	system("pause");
      	return 0;
       }
          
      /* read the input file and put data into the
         array that records points at  */
    
      int readInput(struct custRec *records)
      {
      	FILE *input = fopen("cust.dat","r");
      	int noOfRecords = 0;
      	char tempLane[240];
      	int tempCustId;
      	float tempCustBal;
      	if ( input == 0)	/* can't open cust.dat */
      	{
      		fprintf(stderr,"Can not open cust.dat\n");
      		fprintf(stderr,"please check\n\n");
      		exit(-1);
      	} 	
      	while (fgets(tempLane,240,input))
      	{
      		/* if the first character is a "#" ignore */
      		if (tempLane[0] == '#')
      		{
      			continue;
      		}
      		/* make sure that the line has 2 numbers */
      		if (sscanf(tempLane,"%d, %f",
      				&tempCustId, &tempCustBal) == 2)
      		{
      			records[noOfRecords].ID = tempCustId;
      			records[noOfRecords].Bal = tempCustBal;
      			noOfRecords++;
      		}
      	}
      	
      
      	fclose(input);
      	return noOfRecords;
      }   
       
      
    
    /* sort the records */
    void sortData(struct custRec *custs, int noOfRecs)
      {
      	int inner, outer, didSwap;
      	struct custRec temp;
      	/* sort the array */
      	for (outer = 1; outer < noOfRecs; outer++)
      	{
      		didSwap = 0;
      		for (inner = noOfRecs-1; inner >= outer ; inner--)
      		{
      			if (custs[inner-1].ID > custs[inner].ID )
      			{
      				temp = custs[inner-1];
      				custs[inner-1] = custs[inner];
      				custs[inner] = temp;
      				didSwap = 1;
      			}
      		} /* inner loop */
      		if (didSwap == 0)
      		{
      			break;
      		}
      	} /* outer loop */
      	return ;
      }
      
      void printRecords(struct custRec* custs, int noOfRecs)
     {
      	int i;
      	/* print values */
      	printf("Cust ID    Balance\n");
      	for (i = 0; i < noOfRecs ; i++)
      	{
      		printf("%5d %12.2f\n",
      			custs[i].ID, custs[i].Bal);
      	}
     	return;
     }
    My input file, 'cust.dat', merely contains two columns of values with a header:


    Cust ID Bal

    313 0.00
    453 45.43
    502 71.23
    101 301.56
    892 9.08
    475 192.41
    792 389.00
    912 229.67
    343 18.31
    633 59.54
    999 1.00
    0 0.00


    Thanks for any help.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Does it print before the sort? If not, check how many items are being read from the file (e.g. by printing noOfRecords).

    EDIT:
    And speaking of, look at your format:
    Code:
    "%d, %f"
    Now look at your data.
    Last edited by tabstop; 04-07-2010 at 05:27 PM.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I don't see where you pulled off the header line from the file. You have a char '#' set up to help you, but never use it in the input file.

    You need to do that, first. Then print up the file values, to confirm that you are getting what you should be getting. (bugs can be quite subtle).

    Then do your sorting, and redisplay the data, in sorted order.

    Meter by meter, life is sweeter. Take it a step at a time.

  4. #4
    Registered User
    Join Date
    Feb 2010
    Posts
    19
    Hi tabstop
    No it only prints out

    Before sorting
    Cust ID Balance
    After sorting
    Cust ID Balance
    Press any key to continue...

    I see about the "%d, %f" and my file contents.

    Thanks.

  5. #5
    Registered User
    Join Date
    Feb 2010
    Posts
    19
    Hi Adak
    I deleted the headers and so I only have the two columns of numbers. Still no printing of either the original numbers or the sorted version.

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    After the fgets(), if you print tempLane, what do you get, nothing?


    Next step is seeing if the data gets into your other two temp variables. Print them out and see (or watch them in your debugger).

    Step by step.
    Last edited by Adak; 04-07-2010 at 06:09 PM.

  7. #7
    Registered User
    Join Date
    Feb 2010
    Posts
    19
    I inserted

    Code:
    printf(tempLane,"%d, %f", &tempCustId, &tempCustBal);
    in the function

    Code:
    int readInput(struct custRec *records)
      {
      	FILE *input = fopen("cust.dat","r");
      	int noOfRecords = 0;
      	char tempLane[240];
      	int tempCustId;
      	float tempCustBal;
      	if ( input == 0)	/* can't open cust.dat */
      	{
      		fprintf(stderr,"Can not open cust.dat\n");
      		fprintf(stderr,"please check\n\n");
      		exit(-1);
      	} 	
      	while (fgets(tempLane,240,input))
      	{
      		/* if the first character is a "#" ignore */
      		if (tempLane[0] == '#')
      		{
      			continue;
      		}
      		/* make sure that the line has 2 numbers */
      		if (sscanf(tempLane,"%d, %f",
      				&tempCustId, &tempCustBal) == 2)
      		{
      			records[noOfRecords].ID = tempCustId;
      			records[noOfRecords].Bal = tempCustBal;
      			noOfRecords++;
      		}
      	}
      	
        printf(tempLane,"%d, %f",
      				&tempCustId, &tempCustBal);
      	fclose(input);
      	return noOfRecords;
      }
    but still get nothing.

  8. #8
    Registered User
    Join Date
    Feb 2010
    Posts
    19
    Quote Originally Posted by Adak View Post
    After the fgets(), if you print tempLane, what do you get, nothing?


    Next step is seeing if the data gets into your other two temp variables. Print them out and see (or watch them in your debugger).

    Step by step.
    Hi Adak. How does one go about doing this? Thanks.

  9. #9
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    You may have a blank line at the start of the file?

    Add a t to your file open mode to make it specify "rt" mode. (that used to goof me up often).

    I'm running your program right now.

    The problem is the silly little comma in your sscanf("%d, %f", etc);
    Last edited by Adak; 04-07-2010 at 06:30 PM.

  10. #10
    Registered User
    Join Date
    Feb 2010
    Posts
    19
    Quote Originally Posted by Adak View Post
    You may have a blank line at the start of the file?

    Add a t to your file open mode to make it specify "rt" mode. (that used to goof me up often).

    I'm running your program right now.

    Thanks. I put a 't' in for the 'rt' and checked the input file which does not have any blanks. I also played around with the input file but I still cannot get it to be printed onscreen. I tried another program which only opens the file and it does print the file contents to the screen.

    Code:
    /* seq2.c - an example reading a file */
    
    #include <stdio.h>
    #include <stdlib.h>
    
       int main()
       {
        char letter;
       	char fileLine[100];
       	int i;
       	FILE *fptr;
       	fptr = fopen("cust.dat", "r");
       	if (fptr == 0)
      	{
      		printf("An error occurred while opening the file.\n");
      		exit(1);
      	}
      	while (!feof(fptr))
      	{
      		fgets(fileLine,100,fptr);
      		if (!feof(fptr))
      		{
      			puts(fileLine);
      		}
      	}
      	
      	fclose(fptr);
      	system("pause");
      	return 0;
      }

  11. #11
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Remove that comma from the sscanf() format area, and it works fine.

  12. #12
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    instead of
    Code:
    while (!feof(fptr))
      	{
      		fgets(fileLine,100,fptr);
      		if (!feof(fptr))
      		{
      			puts(fileLine);
      		}
      	}
    use

    Code:
    while (fgets(fileLine,100,fptr))
    {
    	puts(fileLine);
    }
    this is easier to read
    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

  13. #13
    Registered User
    Join Date
    Feb 2010
    Posts
    19
    Quote Originally Posted by Adak View Post
    Remove that comma from the sscanf() format area, and it works fine.
    Thanks a lot Adak. I followed your suggestion and removed the comma between the "%d,%f"
    and the program works fine. Strange that this would be enough to not allow the program to output to the console.

    Code:
    if (sscanf(tempLane, "%d %f",&tempCustId, &tempCustBal) == 2)
    Anyway, I really appreciate your help. I'm learning C just to learn something new. Thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 02-26-2009, 11:48 PM
  2. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM
  3. File Access and Sorting
    By anewhope in forum C Programming
    Replies: 3
    Last Post: 04-17-2002, 08:42 AM
  4. Sorting a Union
    By andy in forum C Programming
    Replies: 4
    Last Post: 11-21-2001, 10:12 AM
  5. Quick File access
    By kwoky in forum C Programming
    Replies: 4
    Last Post: 11-19-2001, 09:38 AM