![]() |
| | #1 |
| Registered User Join Date: Oct 2005
Posts: 24
| Sorting problem.. well actually more of a string problem 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 | |
| | #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 | |
| | #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 | |
| | #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 | |
| | #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 | |
| | #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 | |
![]() |
| Thread Tools | |
| Display Modes | |
|
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 |