C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 11-06-2005, 11:43 PM   #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);
}
fatdunky is offline   Reply With Quote
Old 11-06-2005, 11:48 PM   #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. =)
fatdunky is offline   Reply With Quote
Old 11-07-2005, 10:53 AM   #3
Registered User
 
Join Date: Mar 2005
Location: Mountaintop, Pa
Posts: 1,054
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.
BobS0327 is offline   Reply With Quote
Old 11-07-2005, 04:51 PM   #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);
}
fatdunky is offline   Reply With Quote
Old 11-07-2005, 06:11 PM   #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;
		}
	  }
}
fatdunky is offline   Reply With Quote
Old 11-07-2005, 11:34 PM   #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);
}
fatdunky is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
[Inheritance Hierarchy] User Input on program with constructors. How ? chandreu C++ Programming 8 04-25-2008 02:45 PM
Inheritance Hierarchy for a Package class twickre C++ Programming 7 12-08-2007 04:13 PM
Custom String class gives problem with another prog. I BLcK I C++ Programming 1 12-18-2006 03:40 AM
Message class ** Need help befor 12am tonight** TransformedBG C++ Programming 1 11-29-2006 11:03 PM


All times are GMT -6. The time now is 12:12 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

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