weird symbol saved into the file

This is a discussion on weird symbol saved into the file within the C Programming forums, part of the General Programming Boards category; I am doing my assignment for C and encountered this weird problem. The assignment is about creating a link list ...

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    4

    weird symbol saved into the file

    I am doing my assignment for C and encountered this weird problem.
    The assignment is about creating a link list and saved the data into a file for further uses.

    I input: KOTRA 2 50 45 0.565
    but the output in the file is kontra ? 屯屯屯屯屯屯屯屯屯 I@屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯- 屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯瓽醶?屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯 屯屯屯屯屯屯屯

    Can someone point me my mistake? I am very confuse with link list so I am doing it according to a reference book.
    thanks


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    //#pragma comment( lib, "Wldap32.lib" )
    
    typedef struct Stock 
    {
    	char stockName[10];
    	char stockCode[20];
    	double amountInvested[10];
    	int sharesHeld[10];
    	double currentPrice[10];
    	struct Stock *next;
    	struct Stock *prior;
    }STOCK;
    
    STOCK *start;
    STOCK *last;
    STOCK *find(char *);
    
    void enter(void);
    void search(void);
    void save(void);
    void load(void);
    void list(void);
    void mldelete(STOCK **,STOCK **);
    void dls_store(STOCK *i,STOCK **start, STOCK **last);
    void inputS(char *,char *, int);
    void inputI( char *, int *, int);
    void inputD( char *, double *, int);
    void display(STOCK*);
    int menu_selection(void);
    void call();
    
    int main()
    {
    	start =NULL;
    	last =NULL;
    	
    
    	while(1)
    	{
    		switch(menu_selection())
    		{
    		case 1:
    			load();
    			list();
    			break;
    		case 2: 
    			search();
    			break;
    		case 3: 
    			mldelete(&start, &last);
    			break;
    		case 4: 
    			save();
    			exit(0);
    			break;
    		case 5:
    			enter();
    		}
    	}
    	return 0;
    }
    
    //select an operation.
    int menu_selection(void)
    {
    	char s[80];
    	int c;
    
    	printf("Menu:\n");
    	printf("1. Display list\n");
    	printf("2. Search\n");
    	printf("3. Modify\n");
    	printf("4. Save and Quit\n");
            printf("5. Enter a new stock's details\n");
    	do
    	{
    		printf("Enter your choice:");
    		fgets(s,79,stdin);
    		c = atoi(s);
    	}while (c<0||c>5);
    		return c;
    }
    
    //Load the info from file
    void load(void)
    {
    	STOCK *info;
    	FILE *inp;
    
    	inp=fopen("stock.txt","rb");
    	if(!inp)
    	{
    		printf("Cannot open file.\n");
    		exit(1);
    	}
    
    	//free any previously allocatd memory
    	while(start)
    	{
    		info=start->next;
    		free(info);
    		start=info;
    	}
    
    	//reset top and bottom pointers
    	start = NULL;
    	last= NULL;
    
    	printf("\nLoading File.\n");
    	while(!feof(inp))
    	{
    		info=(STOCK*)malloc(sizeof(STOCK));
    		if(!info)
    		{
    			printf("Out of memory");
    			exit(105);
    		}
    		if(1 !=fread(info,sizeof(STOCK),1,inp))
    			break;
    		dls_store(info, &start, &last);
    
    	}
    
    	if (fclose(inp)==EOF)
    		{
    			printf ("Error in closing file.\n");
    			exit (105);
    		}
    		else 
    		{
    			printf ("File is successfully loaded.\n");
    		}
    }
    
    // create a doubly linked list in sorted order.
    void dls_store(STOCK *i, STOCK **start,STOCK **last)
    {
    	STOCK *old,*p;
    
    	if(*last==NULL)
    	{
    		i->next=NULL;
    		i->prior=NULL;
    		*last=i;
    		*start= i;
    		return;
    	}
    
    	p=*start;
    
    	old=NULL;
    	while(p)
    	{
    		if(strcmp(p->stockName,i->stockName)<0)
    		{
    			old=p;
    			p=p->next;
    		}
    		else
    		{
    			if(p->prior)
    			{
    				p->prior->next=i;
    				i->next=i;
    				i->prior=p->prior;
    				p->prior=i;
    				return;
    			}
    			i->next=p;
    			i->prior=NULL;
    			p->prior=i;
    			*start=i;
    			return;
    		}
    	}
    	old->next=i;
    	i->next=NULL;
    	i->prior=old;
    	*last=i;
    }
    
    //display the entire list
    void list(void)
    {
    	STOCK *info;
    
    	info=start;
    	while(info)
    	{
    		display(info);
    		info=info->next;
    	}
    }
    
    //Print the fields in each address
    void display(STOCK *info)
    {
    	printf("Stock Name\tStock Code\tInvested\tShares Held\tCurrent Prize\n\n");
    	printf("%s",info->stockName);
    	printf("\t%s",info->stockCode);
    	printf("\t%.2f",info->amountInvested);
    	printf("\t%d",info->sharesHeld);
    	printf("\t%.2f",info->currentPrice);
    	printf("\n");
    }
    
    //accept stock name desired
    void search(void)
    {
    	char name[20];
    	STOCK *info;
    
    	printf("Enter stock name to find: ");
    	fgets(name,20,stdin);
    	info=find(name);
    	if(!info)
    		printf("Not Found.\n");
    	else
    		display(info);
    }
    
    //find the stock name
    STOCK *find(char *name)
    {
    	STOCK *info;
    
    	info=start;
    	while(info)
    	{
    		if(!strcmp(name,info->stockName))
    			return info;
    		info=info->next;
    	}
    	printf("Name not found.\n");
    	return NULL;
    }
    
    //remove an element from the list
    void mldelete(STOCK **start,STOCK **last)
    {
    	STOCK *info;
    	char s[90];
    
    	inputS("Enter name: ", s, 20);
    	info=find(s);
    	if(info)
    	{
    		if(*start==info)
    		{
    			*start= info->next;
    			if(*start)
    				(*start)->prior= NULL;
    			else
    				*last= NULL;
    		}
    		else
    		{
    			info->prior->next= info->next;
    			if(info!= *last)
    				info= info->prior;
    			else
    				*last= info->prior;
    		}
    		free(info);
    		enter();
    	}
    	
    }
    
    //Enter stock details
    void enter(void)
    {
    	STOCK *info;
    
    	for(;;)
    	{
    		info=(STOCK*)malloc(sizeof(STOCK));
    		if(!info)
    		{
    			printf("\nout of memory");
    			return;
    		}
    
    		inputS("Enter stock name: ", info->stockName,20);
    		if(!info->stockName[0])
    			break;
    		inputI("Enter stock code: ",info->stockCode,10);
    		inputD("Enter amount invested: ",info->amountInvested,10);
    		inputI("Enter share held: ",info->sharesHeld,10);
    		inputD("Enter current price: ",info->currentPrice,10);
    		dls_store(info,&start,&last);
    		system("cls");
    		return;
    	}
    	
    }
    
    void inputS( char *prompt, char *s, int count)
    {
    	char p[255];
    
    	do
    	{
    		printf(prompt);
    		fgets(p,254, stdin);
    		if(strlen(p)> count)
    			printf("\nToo long.\n");
    	}while(strlen(p)>count);
    
    		p[strlen(p)-1]=0;
    	strcpy_s(s,10,p);
    }
    
    void inputD( char *prompt, double *s, int count)
    {
    	char p[255];
    
    
    	do
    	{
    		printf(prompt);
    		fgets(p,254, stdin);
    		if(strlen(p)> count)
    			printf("\nToo long.\n");
    	}while(strlen(p)>count);
    
    		p[strlen(p)-1]=0;
    	*s=atof(p);
    }
    
    void inputI( char *prompt, int *s, int count)
    {
    	char p[20];
    
    
    	do
    	{
    		printf(prompt);
    		fgets(p,254, stdin);
    		if(strlen(p)> count)
    			printf("\nToo long.\n");
    	}while(strlen(p)>count);
    
    		p[strlen(p)-1]=0;
    	*s=atoi(p);
    }
    
    void save(void)
    {
    	STOCK *info;
    	FILE *outp;
    
    	outp=fopen("stock.txt","wb");
    	if(!outp)
    	{
    		printf("Cannot open file.\n");
    		exit(1);
    	}
    
    	printf("\nSaving file\n");
    
    	info=start;
    	while(info)
    	{
    		fwrite(info, sizeof(STOCK),1,outp);
    		info = info->next;
    	}
    	
    	if (fclose(outp)==EOF)
    		{
    			printf ("Error in closing file\n");
    			exit (105);
    		}
    		else 
    		{
    			printf ("Data successfully being saved.\n");
    		}
    }
    Last edited by gknight; 04-01-2010 at 12:26 AM.

  2. #2
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,806
    #1. In your load function, this looks off:
    Code:
    while(start)
    {
    	info=start->next;
    	free(info);
    	start=info;
    }
    I'm almost certain you'd want to be freeing start instead of info.


    #2. Based on your use of these functions:
    Code:
    void inputS(char *,char *, int);
    void inputI( char *, int *, int);
    void inputD( char *, double *, int);
    ...the first argument should probably be a const char* instead of just a char *.


    #3. You have various places where you are using "magic" numbers:
    Code:
    char s[80];
    ...
    do
    {
    	printf("Enter your choice:");
    	fgets(s,79,stdin);
    
    
    
    ...
    
    
    
    char p[255];
    
    do
    {
    	printf(prompt);
    	fgets(p,254, stdin);
    You should be able to safely use the size of the buffer you're putting the data into:
    Code:
    char s[80];
    ...
    do
    {
    	printf("Enter your choice:");
    	fgets(s,sizeof(s),stdin);
    
    ...
    
    char p[255];
    
    do
    {
    	printf(prompt);
    	fgets(p,sizeof(p), stdin);


    #4. This is wrong:
    Code:
    void inputI( char *prompt, int *s, int count)
    {
        char p[20];
    
        do
        {
            printf(prompt);
            fgets(p,254, stdin);
    #5. Your save and quit option simply writes data to the file before exiting the program. Don't you think you should also free up all the allocated memory as well before exiting the program?

    #6. Is it your intention that the load function is not called until the user selects option 1 "Display list"? If the user goes right to the Search/Modify options they will fail since the list hasn't been loaded yet from the file. If the user enters a bunch of records and stores them on the list and then wishes to "Display list" then the records he's already entered get wiped out and the list is reloaded from the file. I don't think this is the behavior you want in your program although maybe it is. I would think you would call the "load" function somewhere before your menu I/O takes place.

    #7. Don't cast the return value of malloc, you do it in several places within your code:
    Code:
    info=(STOCK*)malloc(sizeof(STOCK));
    #8. This suffers from a flaw:
    Code:
    while(!feof(inp))
    {
    	info=(STOCK*)malloc(sizeof(STOCK));
    	if(!info)
    	{
    		printf("Out of memory");
    		exit(105);
    	}
    	if(1 !=fread(info,sizeof(STOCK),1,inp))
    		break;
    	dls_store(info, &start, &last);
    
    }
    It's not the flaw I at first thought since the break takes care of that. It's that you malloc and then try to read. If the read fails you break out of the loop but you've already allocated memory that you have no way to get back.



    Haven't looked at anything else so far.
    "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

  3. #3
    Registered User
    Join Date
    Apr 2010
    Posts
    4
    I fixed those problem stated in the above post beside the first one. And I solve the problem of the strange symbol by using fscanf instead of fread.

    however, my link list only consists of only the last data in the file and it goes for a infinite loop. Could there be anything wrong with my dls_store, list, and display function?

    I am searching for a sample code that build a doubly linked list.

    Code:
    void dls_store(STOCK *i, STOCK **start,STOCK **last)
    {
    	STOCK *old,*p;
    	
    	if(*last==NULL)
    	{
    		i->next=NULL;
    		i->prior=NULL;
    		*last=i;
    		*start= i;
    		return;
    	}
    
    	p=*start;
    
    	old=NULL;
    	while(p)
    	{
    		if(strcmp(p->stockCode,i->stockCode)<0)
    		{
    			old=p;
    			p=p->next;
    		}
    		else
    		{
    			if(p->prior)
    			{
    				p->prior->next=i;
    				i->next=p;
    				i->prior=p->prior;
    				p->prior=i;
    				return;
    			}
    			i->next=p;
    			i->prior=NULL;
    			p->prior=i;
    			*start=i;
    			return;
    		}
    	}
    	old->next=i;
    	i->next=NULL;
    	i->prior=old;
    	*last=i;
    	return;
    }
    Code:
    void list(void)
    {
    	STOCK *info;
    	int loop;
    
    	info=start;
    	if(info)
    	{
    		printf("\tStock Name\tStock Code\tInvested\tShares Held\tCurrent Prize\n\n");
    		for(loop=0;info;loop++)
    		{	
    			
    			printf("%d\t\t",loop);
    			display(info);
    			info=info->next;
    		}
    	}
    	else
    		printf("No data");
    
    	printf("\n\n");
    
    	return;
    }
    
    //Print the fields in each address
    void display(STOCK *info)
    {
    			printf("%s",info->stockName);
    			printf("\t\t%s",info->stockCode);
    			printf("\t\t%s",info->amountInvested);
    			printf("\t\t%s",info->sharesHeld);
    			printf("\t\t%s",info->currentPrice);
    			printf("\n");
    	return;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A development process
    By Noir in forum C Programming
    Replies: 37
    Last Post: 07-10-2011, 11:39 PM
  2. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 01:36 PM
  3. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  4. Simple File encryption
    By caroundw5h in forum C Programming
    Replies: 2
    Last Post: 10-13-2004, 11:51 PM
  5. Linking error
    By DockyD in forum C++ Programming
    Replies: 10
    Last Post: 01-20-2003, 05:27 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21