Thread: need help with writing to text file / reading from text file

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    40

    need help with writing to text file / reading from text file

    Hi,

    I have an array of structures allowing user to enter info on 5 stocks. I have calculated initial cost, current cost, and profit. I have also bubble sorted the array of structures alphabetically by stock name and printed sorted array.

    PROBLEM: I'm trying to save array of structures to a text file, retrieve it and then print the text file. I've successfully saved to the text file, but when I have the program retrieve the text file and print out the file, I get a problem. Why is the purchase date always being changed to "purchase" instead of staying as the date that is correctly listed in the text file?

    Code:
    #include<stdio.h>
    #include<string.h>
    #define SIZE 5
    
    struct Stock
    {
    	char stock_name[9], purchase_date[9];
    	int num_shares;
    	float buying_price, current_price, yearly_fees, initial_cost, current_cost, profit;
    };
    
    void load(struct Stock s[], int n)
    {
    	for(int i=0; i<n; i++)
    	{
    		printf("Enter stock name: ");
    		gets(s[i].stock_name);
    	
    		printf("Enter purchase date: ");
    		gets(s[i].purchase_date);
    
    		printf("Enter number of shares: ");
    		scanf("%d", &s[i].num_shares);
    
    		printf("Enter buying price per share: ");
    		scanf("%f", &s[i].buying_price);
    
    		printf("Enter current price per share: ");
    		scanf("%f", &s[i].current_price);
    
    		printf("Enter yearly fees: ");
    		scanf("%f", &s[i].yearly_fees);
    		
    		printf("\n");
    		
    		s[i].initial_cost = s[i].num_shares * s[i].buying_price;
    		s[i].current_cost = s[i].num_shares * s[i].current_price;
    		s[i].profit = s[i].current_cost - s[i].initial_cost - s[i].yearly_fees;	
    
    		fflush(stdin);
    	}
    }
    
    void sortStock(Stock s[], int n)
    {
    	int i, j;
    	char t[9];
    
    	for(i=0; i<n-1; i++)
    		for(j=0; j<n-1; j++)
    			if (strcmp(s[j].stock_name, s[j+1].stock_name)>0)
    			{
    				strcpy(t, s[j].stock_name);
    				strcpy(s[j].stock_name, s[j+1].stock_name);
    				strcpy(s[j+1].stock_name, t);
    			}
    }
    
    void saveText(Stock s[], int n)
    {
    	int j;
    	FILE *f;
    	f=fopen("c:\\stock_data.txt","w");
    	
    	for(j=0; j<n; j++)
    	{
    		fprintf(f, "%s\n", s[j].stock_name);
    		fprintf(f, "Purchase Date: %s\n", s[j].purchase_date);
    		fprintf(f, "Intial Cost: $%0.2f\n", s[j].initial_cost);
    		fprintf(f, "Current Cost: $%0.2f\n", s[j].current_cost);
    		fprintf(f, "Profit: $%0.2f\n\n", s[j].profit);
    	}
    
    	fclose(f);
    }
    
    void retText(struct Stock s[], int n)
    {
    	FILE *f;
    	int j;
    	
    	f=fopen("c:\\stock_data.txt","r");
    	for(j=0; j<n; j++)
    	{
    		fgets(s[j].stock_name, sizeof(s[j].stock_name), f);
    		fgets(s[j].purchase_date, sizeof(s[j].purchase_date),f);
    		fscanf(f, "%f %f %f\n", s[j].initial_cost, s[j].current_cost, s[j].profit);		
    	} 
    
    	fclose(f);
    }
    void print(Stock s[], int n)
    {
    	for(int j=0; j<n; j++)
    	{
    		printf("Stock Name: %s", s[j].stock_name);
    		printf("\nPurchase Date: %s\n", s[j].purchase_date);
    		printf("Initial Cost: $%0.2f\n", s[j].initial_cost);
    		printf("Current Cost: $%0.2f\n", s[j].current_cost);
    		printf("Profit: $%0.2f\n\n", s[j].profit);
    	}
    }
    
    void main()
    {
    	Stock s[SIZE];
    	load(s, SIZE);
    
    	sortStock(s, SIZE); 
    	print(s, SIZE);
    
    	saveText(s, SIZE);
    	retText(s, SIZE);
    	print(s, SIZE);
    }
    Last edited by x2x3i5x; 05-05-2010 at 01:54 PM.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Because you print "purchase" to the file. So when you read it in....

  3. #3
    Registered User
    Join Date
    Sep 2009
    Posts
    40
    Quote Originally Posted by tabstop View Post
    Because you print "purchase" to the file. So when you read it in....
    I believe the error lies in the following statements in my code: fgets(s[j].purchase_date, sizeof(s[j].purchase_date),f); and printf("\nPurchase Date: %s\n", s[j].purchase_date);


    But it looks ok to me, so I'm a little lost on how best to fix the issue here,, I want to keep that print function as is, because it works fine to printout the the results of the bubblesort.
    Last edited by x2x3i5x; 05-05-2010 at 02:03 PM.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    This results in undefined behaviour:
    Code:
    fflush(stdin);
    That should never appear in a legal C program. It probably does not account for your problem, but as the term "undefined behavior" implies, once introduced, it becomes impossible to say why anything has gone wrong. You need to read this:

    STDIN pitfalls

    Also, contemplate:
    Code:
    		fprintf(f, "Purchase Date: %s\n", s[j].purchase_date);
         [.........]
    		fgets(s[j].purchase_date, sizeof(s[j].purchase_date),f);
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    Sep 2009
    Posts
    40
    Quote Originally Posted by MK27 View Post
    This results in undefined behaviour:
    Code:
    fflush(stdin);
    That should never appear in a legal C program. It probably does not account for your problem, but as the term "undefined behavior" implies, once introduced, it becomes impossible to say why anything has gone wrong. You need to read this:

    STDIN pitfalls

    Also, contemplate:
    Code:
    		fprintf(f, "Purchase Date: %s\n", s[j].purchase_date);
         [.........]
    		fgets(s[j].purchase_date, sizeof(s[j].purchase_date),f);
    thank you for the fflush(stdin) tip. And ok, I'll check the thing you highlighted, I guess fprint is printing out the word "purchase" to textfile and fgets is reading that same word out of the textfile. Maybe I should just remove the words "purchase date".
    Last edited by x2x3i5x; 05-05-2010 at 02:12 PM.

  6. #6
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    #1
    Code:
    void load(struct Stock s[], int n)
    {
        for(int i=0; i<n; i++)
        {
            printf("Enter stock name: ");
            gets(s[i].stock_name);
    	
            printf("Enter purchase date: ");
            gets(s[i].purchase_date);
    
            ...
        }
    }
    There are better choices than gets. You are already using fgets elsewhere so why not everywhere else?



    #2
    Code:
    void main()
    Ugh.



    #3
    Code:
    void sortStock(Stock s[], int n)
    {
        int i, j;
        char t[9];
    
        for(i=0; i<n-1; i++)
            for(j=0; j<n-1; j++)
                if (strcmp(s[j].stock_name, s[j+1].stock_name)>0)
                {
                    strcpy(t, s[j].stock_name);
                    strcpy(s[j].stock_name, s[j+1].stock_name);
                    strcpy(s[j+1].stock_name, t);
                }
    }
    All you do is manage to order around the stock names. No sorting of the other data - dates, prices, fees, etc - occurs at all here so your data isn't synch'd after sorting.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  7. #7
    Registered User
    Join Date
    Sep 2009
    Posts
    40
    @hk_mp5kpdw, I'm supposed to have the program print out all of the stock data for each stock and the order printed out will be in alphabetical order on the name. So, what would I have to do in that case?

    @ MK27, after removing the words "Purchase Date" in that printf and I run the program again, it runs fine up to the point where it gets to the point where "fscanf(f, "%f %f %f\n", s[j].initial_cost, s[j].current_cost, s[j].profit);" comes in and the app crashes. That is what the Visual C++ 2008 express's debugger tells me is where the program stops.

    Anybody know why I'm getting that problem?
    Last edited by x2x3i5x; 05-05-2010 at 02:26 PM.

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Since you are using the debugger check what the value of j is at that point (eg, whether this happens the first time, or subsequently).
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Registered User
    Join Date
    Sep 2009
    Posts
    40
    Quote Originally Posted by MK27 View Post
    Since you are using the debugger check what the value of j is at that point (eg, whether this happens the first time, or subsequently).
    ok, I tested when I change the SIZE to 1, no error. But when I have 2 or more, I get an error.

    when I have SIZE as 1, I can get something like the following as output (click on links to see the screenshots):

    http://img227.imageshack.us/img227/3556/cmd1.jpg Why all the extra spaces in the printout just before the press any key to continue text?

    when I have SIZE as 2, I see that J is at 1, and the following appears, as per the debugger:

    http://img3.imageshack.us/img3/4773/cmd2.jpg


    Also, I'm wondering when hk_mp5kpdw said
    "All you do is manage to order around the stock names. No sorting of the other data - dates, prices, fees, etc - occurs at all here so your data isn't synch'd after sorting."

    I'm supposed to have the program print out all of the stock data for each stock and the order printed out will be in alphabetical order on the name. I think I did that, unless I need to do something else too?
    Last edited by x2x3i5x; 05-05-2010 at 02:48 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems installing Mingw5.1.4
    By BlackOps in forum C Programming
    Replies: 2
    Last Post: 07-26-2009, 03:28 AM
  2. Replies: 7
    Last Post: 02-02-2009, 07:27 AM
  3. reading text file to struct help needed!
    By werdy666 in forum C++ Programming
    Replies: 2
    Last Post: 01-25-2009, 11:37 AM
  4. Reading out of and writing into the same file
    By Wiretron in forum C Programming
    Replies: 8
    Last Post: 12-30-2006, 02:04 PM
  5. Reading a mixed Text and decimal file into an array
    By djamie in forum C Programming
    Replies: 3
    Last Post: 08-05-2003, 06:25 AM