Thread: Sorting problem.. well actually more of a string problem

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    24

    Sorting problem.. well actually more of a string problem

    Hi guys,

    im trying to write a program that will sort a file. But that you can all give the option of using a delimeter and colum to sort by. (by typing /c in command prompt)

    eg if the file had the line
    mark|is|asking|this|question
    you would enter | as the delimeter and if you wanted to sort the colum mark was in you would enter in 1 as the colum to sort by.
    Only problem is it crashes and doesnt sort. It still work with out the /c option.

    I had it working fine and i documented the functions i changed.

    This isnt homework or anything im just trying to learn c in my sparetime at work =). And improvments you think i need to my program ill be glad to hear them

    Heres the code (its pretty long sorry)

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdlib.h>
    
    
    /***************************************
    This program shall SORT using a binary tree.
    
    ©2005 Mark Crick
    ****************************************/
    
    
    typedef struct SBinaryTree
    {
        char *SBinaryTreeData;
        struct SBinaryTree *SBinaryTreeLeft;
        struct SBinaryTree *SBinaryTreeRight;
    } nBinaryTreeNode;
    
    char dilimeter;
    int columNumber;
    char byColum = 'f';
    
    nBinaryTreeNode *CreateBTNode (char *SBinaryTreeData, int dataSize)// Create tree
    {
    	nBinaryTreeNode *nTempNode =  malloc(sizeof (nBinaryTreeNode));
        nTempNode->SBinaryTreeData = (char *)calloc (dataSize, sizeof (char));
    
        strncpy (nTempNode->SBinaryTreeData, SBinaryTreeData,dataSize);
        nTempNode->SBinaryTreeLeft = NULL;
        nTempNode->SBinaryTreeRight = NULL;
    
        return nTempNode;
    }
    void splitStringToDilimeter(char string[],char retVal[BUFSIZ], int retValSize)
    {
    	int i;  // I THINK THE PROBLEM IS WITH THIS FUNCTION OR THE ONE BELOW.*************************************
    	int columCount = 0; //Colum program is looking at
    	int lastDelIndex = 0;//Position of Last delimeter
    	int strSize; //Size of string
    
    	strSize = strlen(string); // get size of string
    	printf("stringsize :%i\n ",strSize);
    
    	for(i = 0; i < strSize;i++) //Loop through whole of provided string.
    	{
    		if(string[i] == dilimeter) //If char in string is = to the specified dilimeter. '|' in example
    		{
    			columCount++; 					//Add one to colum count to specify that program is in a new colum
    			if(columCount == columNumber)	//If we are now in the colum user specified to sort in
    			{
    				int x;
    				int i2 = lastDelIndex;
    
    				for(x = 0; x < retValSize && i2 < retValSize && i2 < i;x++,i2++)
    				{
    					retVal[x] = string[i2];  //copy array section from the last dilimeter postion to current postion
    				}								// Which should be another dilimeter
    				x++;
    				if(x < retValSize)
    				retVal[x] = '\0';				//Add /0 to end of new string.
    			}
    			else
    			{
    				lastDelIndex = i;				//If this isnt the colum specified by the user record index and last
    												//dilimeter
    				lastDelIndex++;
    			}
    		}
    	}
    }
    int sortTree(char *string1, char* string2) //**********This could be where the problem is
    {
    	 char *tempString; //String for splitStringToDilimeter to return a result too
    	 char *tempString2;//String for splitStringToDilimeter to return a result too
    	 int retVal; // return value for this method
    
    	 splitStringToDilimeter(string1,tempString,BUFSIZ);
    	 splitStringToDilimeter(string2,tempString2,BUFSIZ);
    	 retVal = strcmp(tempString,tempString2);
    	 printf("tempString  : %s\ntempString2 : %s\nretVal %i\n",tempString,tempString2,retVal);
    	 return retVal;
    }
    
    nBinaryTreeNode *AddBTNode (char *line, nBinaryTreeNode *BTreeRootIn ) //CHANGED THE FUNCTION TOO.
    {
        if (BTreeRootIn == NULL)
            return CreateBTNode (line,BUFSIZ);
        if(byColum == 't')							// If /c flag has been used  use sortTree rather then strcmp
        {
       		 if (sortTree (line, BTreeRootIn->SBinaryTreeData) < 0)
           		BTreeRootIn->SBinaryTreeLeft = AddBTNode (line, BTreeRootIn->SBinaryTreeLeft);
        	 else
            	BTreeRootIn->SBinaryTreeRight = AddBTNode (line, BTreeRootIn->SBinaryTreeRight);
     	}
     	else
     	{
    		 if (strcmp (line, BTreeRootIn->SBinaryTreeData) < 0)
    		     BTreeRootIn->SBinaryTreeLeft = AddBTNode (line, BTreeRootIn->SBinaryTreeLeft);
    		 else
            	 BTreeRootIn->SBinaryTreeRight = AddBTNode (line, BTreeRootIn->SBinaryTreeRight);
    	}
        return BTreeRootIn;
    }
    
    void WriteFileFromTree(nBinaryTreeNode *BTRootOut , FILE *filePtr)// Recursive method writes file according to tree struct
    {
      	if (BTRootOut->SBinaryTreeLeft != NULL)
    		WriteFileFromTree (BTRootOut->SBinaryTreeLeft,filePtr);
    
    	fprintf (filePtr, "%s", BTRootOut->SBinaryTreeData);
    
    	if (BTRootOut->SBinaryTreeRight != NULL)
            WriteFileFromTree (BTRootOut->SBinaryTreeRight,filePtr);
    }
    void OpenWriteFileFromTree(char *fileName,nBinaryTreeNode *BTRootOut)//Opens file to write to then calls method to write tree to file
    {
    	FILE *filePtr;
    
    	if((filePtr = fopen(fileName,"w")) != NULL)
    	{
    		WriteFileFromTree(BTRootOut,filePtr);
    		if(fclose(filePtr)==EOF)
    		{
    			perror("Sort");
    			exit(1);
    		}
    	}
    	else
    	{
    		fclose(filePtr); //Didnt catch close errors here because there is allready an open error.
    		perror("Sort");	// And code would be the same if there was error or no error
    		exit(1);
    	}
    }
    
    nBinaryTreeNode  *ReadFileToTree(char *fileName)// This will read the text file into the buffer array
    {
      	FILE *filePtr;
    	nBinaryTreeNode *BTRoot = NULL;
    
      	if((filePtr = fopen(fileName,"r")) != NULL)
    	{
        		char szReadLine[BUFSIZ]= {0};
        		while (fgets(szReadLine, sizeof(szReadLine), filePtr) != NULL)
    			{
    			    BTRoot = AddBTNode (szReadLine, BTRoot);
    			}
    			if(fclose(filePtr)==EOF)
    			{
    				perror("Sort");
    				exit(1);
    			}
    	}
    	else
    	{
    		fclose(filePtr); //Didnt catch close errors here because there is allready an open error.
    		perror("Sort"); // And code would be the same if there was error or no error
    		exit(1);
    	}
    	return BTRoot;
    }
    void getInput(char *question, char array[BUFSIZ])
    {
    	char *arrayPtr = array;
    	int i;
    	printf(question);
    
    	fgets(array,BUFSIZ,stdin);
    	for(i = 0;i < BUFSIZ;i++, arrayPtr++)
    	{
    		if(*arrayPtr == '\n')
    		{
    		   arrayPtr++;
    		   *arrayPtr = '\0';
    		  	break;
    		}
    	}
    }
    int main(int argc, char **argv)
    {	if(argc == 3 )
    	{
    		char input[BUFSIZ];
    		byColum = 't';
    		getInput("Please enter the field Delimiter: \n",input);
    		dilimeter =  input[0];
    	    getInput("Please enter the colum number to sort by: \n",input);
    		columNumber = strtol(input,NULL,10);
    	}
    	if(argc == 2)
    	{
    		nBinaryTreeNode *BTRoot = ReadFileToTree(argv[1]);
    		OpenWriteFileFromTree(argv[1],BTRoot);
    		printf("Sort.exe wOOt!. \n");
    	}
    	else if(argc == 3 )
    	{
    
    		nBinaryTreeNode *BTRoot = ReadFileToTree(argv[1]);
    		OpenWriteFileFromTree(argv[1],BTRoot);
    		printf("Sort.exe wOOt!. \n");
    	}
    	else
    	{
    		printf("Sort: Incorrect argument \nSyntax: Sort [file to sort] [file to write sorted data too] \n/c \t \t \t \t Sort by colum \nPress Any key to Continue\n");
    		exit(1);
    	}
    	return(0);
    }

  2. #2
    Registered User
    Join Date
    Oct 2005
    Posts
    24
    Oh and ive been fooling around with this for a while trying to get it work. So there might be some usless stuff in there (inculdes i dont need, printf's i dont ect...) sorry. =)

  3. #3
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    I would suggest that you concentrate on the code for parsing the command line. When you're totally comfortable with that code then go on to modify the file sort function.

  4. #4
    Registered User
    Join Date
    Oct 2005
    Posts
    24
    Hehe whoops yeah sorry forgot to fix that.

    Code:
    int main(int argc, char **argv)
    {
    	if(argc == 2)
    	{
    		nBinaryTreeNode *BTRoot = ReadFileToTree(argv[1]);
    		OpenWriteFileFromTree(argv[1],BTRoot);
    		printf("Sort.exe wOOt!. \n");
    	}
    	else if(argc == 3 && (strcmp(argv[2],"/c") == 0) )
    	{
    		nBinaryTreeNode *BTRoot;
    		char input[BUFSIZ];
    		byColum = 't';
    		getInput("Please enter the field Delimiter: \n",input);
    		dilimeter =  input[0];
    		getInput("Please enter the colum number to sort by: \n",input);
    
    		columNumber = strtol(input,NULL,10);
    		BTRoot = ReadFileToTree(argv[1]);
    		OpenWriteFileFromTree(argv[1],BTRoot);
    		printf("Sort.exe wOOt!. \n");
    	}
    	else
    	{
    		printf("Sort: Incorrect argument \nSyntax: Sort [file to sort] \n/c \t \t \t \t Sort by colum \nPress Any key to Continue\n");
    		exit(1);
    	}
    	return(0);
    }

  5. #5
    Registered User
    Join Date
    Oct 2005
    Posts
    24
    Ive actually man a huge change to the sorting function as well now. (based on a thread i saw on the board)

    Code:
    void splitStringToDilimeter(char *string,char *retVal)
    {
    	  unsigned int count = 0;
    	  size_t sublen;
    	  while((retVal = strtok(string,dilimeter)))
    	  {
    	   	count++;
    	   	if(count == columNumber)
    	   	{
    	   		break;
    		}
    	   	else
    	   	{
    			sublen = strlen(retVal);
    			string += sublen;
    		}
    	  }
    }

  6. #6
    Registered User
    Join Date
    Oct 2005
    Posts
    24
    Heh well i actually figured it out, so dont worry guys but thanks anyway.

    Here my code in the end if your intrested.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdlib.h>
    
    
    /***************************************
    This program shall SORT using a binary tree.
    
    ©2005 Mark Crick
    ****************************************/
    
    
    typedef struct SBinaryTree
    {
        char *SBinaryTreeData;
        struct SBinaryTree *SBinaryTreeLeft;
        struct SBinaryTree *SBinaryTreeRight;
    } nBinaryTreeNode;
    
    char *dilimeter;
    unsigned int columNumber;
    char byColum = 'f';
    
    nBinaryTreeNode *CreateBTNode (char *SBinaryTreeData, int dataSize)// Create tree
    {
    	nBinaryTreeNode *nTempNode =  malloc(sizeof (nBinaryTreeNode));
        nTempNode->SBinaryTreeData = (char *)calloc (dataSize, sizeof (char));
    
        strncpy (nTempNode->SBinaryTreeData, SBinaryTreeData,dataSize);
        nTempNode->SBinaryTreeLeft = NULL;
        nTempNode->SBinaryTreeRight = NULL;
    
        return nTempNode;
    }
    char *splitStringToDilimeter(char *string)//Split string according to dilimeter
    {										  //And return the substring specified by
    	  char *retVal,*tmpStr;				  //columNumber
    	  unsigned int count = 0;
    	  size_t sublen ;
    	  tmpStr = strdup(string);
    
    	  retVal = strtok(tmpStr,dilimeter);
    	  do
    	  {
    			count++;
    			if(count == columNumber)
    			{
    				break;
    			}
    	   }
    	   while((retVal = strtok(NULL,dilimeter)));
    
    	return retVal;
    }
    int sortTree(char *string1, char* string2)
    {
    	 char *tempString = splitStringToDilimeter(string1);
    	 char *tempString2 = splitStringToDilimeter(string2);
    	 //printf("String1 : %s\nString2 : %s\ntempString  : %s\ntempString2 : %s\n",string1,string2,tempString,tempString2);
    	 return strcmp(tempString,tempString2);
    }
    
    nBinaryTreeNode *AddBTNode (char *line, nBinaryTreeNode *BTreeRootIn )
    {
        if (BTreeRootIn == NULL)
            return CreateBTNode (line,BUFSIZ);
        if(byColum == 't')							// If /c flag has been used  use sortTree rather then strcmp
        {
       		 if (sortTree (line, BTreeRootIn->SBinaryTreeData) < 0)
           		BTreeRootIn->SBinaryTreeLeft = AddBTNode (line, BTreeRootIn->SBinaryTreeLeft);
        	 else
            	BTreeRootIn->SBinaryTreeRight = AddBTNode (line, BTreeRootIn->SBinaryTreeRight);
     	}
     	else
     	{
    		 if (strcmp (line, BTreeRootIn->SBinaryTreeData) < 0)
    		     BTreeRootIn->SBinaryTreeLeft = AddBTNode (line, BTreeRootIn->SBinaryTreeLeft);
    		 else
            	 BTreeRootIn->SBinaryTreeRight = AddBTNode (line, BTreeRootIn->SBinaryTreeRight);
    	}
        return BTreeRootIn;
    }
    
    void WriteFileFromTree(nBinaryTreeNode *BTRootOut , FILE *filePtr)
    {										// Recursive method writes file according to tree struct
      	if (BTRootOut->SBinaryTreeLeft != NULL)
    		WriteFileFromTree (BTRootOut->SBinaryTreeLeft,filePtr);
    
    	fprintf (filePtr, "%s", BTRootOut->SBinaryTreeData);
    
    	if (BTRootOut->SBinaryTreeRight != NULL)
            WriteFileFromTree (BTRootOut->SBinaryTreeRight,filePtr);
    }
    void OpenWriteFileFromTree(char *fileName,nBinaryTreeNode *BTRootOut)//Opens file to write to then calls
    {																	 //method to write tree to file
    	FILE *filePtr;
    
    	if((filePtr = fopen(fileName,"w")) != NULL)
    	{
    		WriteFileFromTree(BTRootOut,filePtr);
    		if(fclose(filePtr)==EOF)
    		{
    			perror("Sort");
    			exit(1);
    		}
    	}
    	else
    	{
    		fclose(filePtr); //Didnt catch close errors here because there is allready an open error.
    		perror("Sort");	// And code would be the same if there was error or no error
    		exit(1);
    	}
    }
    
    nBinaryTreeNode  *ReadFileToTree(char *fileName)// This will read the text file into the buffer array
    {
      	FILE *filePtr;
    	nBinaryTreeNode *BTRoot = NULL;
    
      	if((filePtr = fopen(fileName,"r")) != NULL)
    	{
        		char szReadLine[BUFSIZ]= {0};
        		while (fgets(szReadLine, sizeof(szReadLine), filePtr) != NULL)
    			{
    			    BTRoot = AddBTNode (szReadLine, BTRoot);
    			}
    			if(fclose(filePtr)==EOF)
    			{
    				perror("Sort");
    				exit(1);
    			}
    	}
    	else
    	{
    		fclose(filePtr); //Didnt catch close errors here because there is allready an open error.
    		perror("Sort"); // And code would be the same if there was error or no error
    		exit(1);
    	}
    	return BTRoot;
    }
    void getInput(char *question, char array[BUFSIZ])
    {
    	char *arrayPtr = array;
    	int i;
    	printf(question);
    
    	fgets(array,BUFSIZ,stdin);
    	for(i = 0;i < BUFSIZ;i++, arrayPtr++)
    	{
    		if(*arrayPtr == '\n')
    		{
    		   arrayPtr++;
    		   *arrayPtr = '\0';
    		  	break;
    		}
    	}
    }
    int main(int argc, char **argv)
    {
    	if(argc == 2)
    	{
    		nBinaryTreeNode *BTRoot = ReadFileToTree(argv[1]);
    		OpenWriteFileFromTree(argv[1],BTRoot);
    		printf("Sort.exe wOOt!. \n");
    	}
    	else if(argc == 3 && (strcmp(argv[2],"/c") == 0) )
    	{
    		nBinaryTreeNode *BTRoot;
    		char input[BUFSIZ];
    		byColum = 't';
    		dilimeter = malloc(sizeof(input));
    		getInput("Please enter the field Delimiter: \n",dilimeter);
    		getInput("Please enter the colum number to sort by: \n",input);
    
    		columNumber = strtol(input,NULL,10);
    		BTRoot = ReadFileToTree(argv[1]);
    		OpenWriteFileFromTree(argv[1],BTRoot);
    		free(dilimeter);
    		printf("Sort.exe wOOt!. \n");
    	}
    	else if(argc == 4 && (strcmp(argv[3],"/c") == 0) )
    	{
    		nBinaryTreeNode *BTRoot;
    		char input[BUFSIZ];
    		byColum = 't';
    		dilimeter = malloc(sizeof(input));
    		getInput("Please enter the field Delimiter: \n",dilimeter);
    		getInput("Please enter the colum number to sort by: \n",input);
    
    		columNumber = strtol(input,NULL,10);
    		BTRoot = ReadFileToTree(argv[1]);
    		OpenWriteFileFromTree(argv[2],BTRoot);
    		free(dilimeter);
    		printf("Sort.exe wOOt!. \n");
    	}
    	else
    	{
    		printf("Sort: Incorrect argument \nSyntax: Sort [file to sort] [file to write sorted data too:Optional] \n/c \t \t \t \t Sort by colum \nPress Any key to Continue\n");
    		exit(1);
    	}
    	return(0);
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 04-25-2008, 02:45 PM
  2. Inheritance Hierarchy for a Package class
    By twickre in forum C++ Programming
    Replies: 7
    Last Post: 12-08-2007, 04:13 PM
  3. Custom String class gives problem with another prog.
    By I BLcK I in forum C++ Programming
    Replies: 1
    Last Post: 12-18-2006, 03:40 AM
  4. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM