Strange things appear on running the program
I'm fixing a program but I'm facing a problem and I cant really realize what's the wrong on the code. I would appreciate any help. I didn't post all the code, but I think with this part you ca开发者_开发问答n get an idea of it. With the following function enter() I want to add user commands' data to a list. eg. user give the command: "en james bond 007 gun" ["en" means "enter" on command prompt]
'james' is supposed to be the name, 'bond' the surname, 007 the amount and the rest is the description. I use strtok in order to 'cut' the command, then I put each name on a temp array. Then I call InsertSort in order to put the data on a linked list but in alphabetical order depending on the surname that users give. I want to keep the list on order and put each time the elements on the right position.
Also, maybe there is a fault on InsertSort() and SortedInsert()... as data aren't written on the list as they ought to.
/* struct for all the data that user enters on file */
typedef struct catalog
{
char short_name[50];
char surname[50];
signed int amount;
char description[1000];
struct catalog *next;
}catalog,*catalogPointer;
catalogPointer current;
catalogPointer head = NULL;
void enter(void)//user command: en <name> <surname> <amount> <description>
{ int n,j=2,k=0;
char temp[1500];
char command[1500];
while (command[j]!=' ' && command[j]!='\0')
{ temp[k]=command[j];
j++;
k++;
}
temp[k]='\0';
char *curToken = strtok(temp," ");
printf("temp is:%s \n",temp);
char short_name[50],surname[50],description[1000];
signed int amount;
//short_name=(char *)malloc(sizeof (char *));
//surname=(char *)malloc(sizeof (char *));
//description=(char *)malloc(sizeof (char *));
//amount=(int *)malloc(sizeof (int *));
printf("\nWhat you entered for saving:\n");
for (n = 0; curToken !='\0'; ++n)
{
if (curToken)
{
strncpy(short_name, curToken, sizeof (char *)); /
}
printf("Short Name: %s \n",short_name);
curToken = strtok(NULL," ");
if (curToken)
strncpy(surname, curToken, sizeof (char *)); /
printf("SurName: %s \n",surname);
curToken = strtok(NULL," ");
if (curToken)
{
char *chk;
amount = (int) strtol(curToken, &chk, 10);
if (!isspace(*chk) && *chk != 0)
fprintf(stderr,"Warning: expected integer value for amount, received %s instead\n",curToken);
}
printf("Amount: %d \n",amount);
curToken = strtok(NULL,"\0");
if (curToken)
{ strncpy(description, curToken, sizeof (char *));
}
printf("Description: %s \n",description);
break;
}
if (findEntryExists(head, surname) != NULL)
printf("\nAn entry for <%s %s> is already in the catalog!\nNew entry not entered.\n",short_name,surname);
else
{
printf("\nTry to entry <%s %s %d %s> in the catalog list!\n",short_name,surname,amount,description);
InsertSort(&head,short_name, surname, amount, description);
printf("\n**Entry done!**\n");
}
// Maintain the list in alphabetical order by surname.
}
/********Uses special case code for the head end********/
void SortedInsert(catalog** headRef, catalogPointer newNode,char short_name[],char surname[],signed int amount,char description[])
{
strcpy(newNode->short_name, short_name);
strcpy(newNode->surname, surname);
newNode->amount=amount;
strcpy(newNode->description, description);
// Special case for the head end
if (*headRef == NULL||(*headRef)->surname >= newNode->surname)
{ newNode->next = *headRef;
*headRef = newNode;
}
else
{ // Locate the node before the point of insertion
catalogPointer current = *headRef;
catalogPointer temp=current->next;
while ( temp!=NULL )
{
if(strcmp(temp->surname,newNode->surname)<0 )
current = temp;
}
newNode->next = temp;
temp = newNode;
}
}
// Given a list, change it to be in sorted order (using SortedInsert()).
void InsertSort(catalog** headRef,char short_name[],char surname[],signed int amount,char description[])
{
catalogPointer result = NULL; // build the answer here
catalogPointer current = *headRef; // iterate over the original list
catalogPointer next;
while (current!=NULL)
{
next = current->next; // tricky - note the next pointer before we change it
SortedInsert(&result,current,short_name,surname,amount,description);
current = next;
}
*headRef = result;
}
Running the program I get these strange things (garbage?)...
Choose your selection:
en james bond 007 gun
Your command is: en james bond 007 gun
temp is:james
What you entered for saving: Short
Name: james
SurName: Amount: 0Description: 0T�Г
Try to entry james 0 0T�Г in the catalog list!
Entry done!
Also I'm facing a problem on how to use the 'malloc' on this program.
Thanks in advance. . .
UPDATE: I made an other function for entry. But somehow strange i get segmentation for strcpy! That's it:
catalogPointer newEntry (char short_name[], char surname[], signed int amount, char description[])
{
catalogPointer newNode,first,second,tmp;
first=head;
second=NULL;
strcpy(newNode->short_name, short_name); //SEGMENTATION
strcpy(newNode->surname, surname);
newNode->amount=amount;
strcpy(newNode->description, description);
while (first!=NULL)
{ if (strcmp(surname,first->surname)>0)
second=first;
else if (strcmp(surname,first->surname)==0)
{
if (strcmp(short_name,first->short_name)>0)
second=first;
}
first=first->next;
}
if (second==NULL)
{ newNode->next=head;
head=newNode;
}
else
{ tmp=second->next;
newNode->next=tmp;
first->next=newNode;
}
}
Solution
The direct reason of your problem is here:
while (command[j]!=' ' && command[j]!='\0')
{ temp[k]=command[j];
j++;
k++;
}
What you are doing here is copying the contents of command
into temp
until the first space character. That is, you only copy "james"
. Thus after the short name, there is nothing more for strtok
to parse, so the other buffers don't get initialized properly and contain only garbage.
Update: To copy stuff after the first space character, use strchr
and strcpy
instead of that loop:
char* params = strchr(command, ' ') + 1;
strcpy(temp, params);
Other observations
Apart from this, you give the size of the destination buffer incorrectly here:
strncpy(surname, curToken, sizeof (char *));
should be
strncpy(surname, curToken, 49);
Secondly: the loop expression in
for (n = 0; curToken !='\0'; ++n)
should be
for (n = 0; curToken; ++n)
otherwise the loop will not terminate correctly when all tokens have been parsed.
You don't seem to be filling command
with anything, so you are tokenising whatever garbage was on the stack.
精彩评论