|
-
April 9th, 2012, 02:17 AM
#16
Re: Structure Linked Lists: Searching for Words.
The typedef is this:
Code:
typedef struct artist* artistNodePtr;
So, if I do:
Code:
artistNodePtr aPtr;
I now have a pointer that can point to an artist struct. You are making this harder than it needs to be. By writing:
Code:
artistNodePtr *sPtr
You are passing in a pointer to a pointer, and that seems unnecessary.
-
April 9th, 2012, 03:57 AM
#17
Re: Structure Linked Lists: Searching for Words.
-
April 9th, 2012, 04:33 AM
#18
Re: Structure Linked Lists: Searching for Words.
It can be a simple thing to overlook
-
April 9th, 2012, 11:56 AM
#19
Re: Structure Linked Lists: Searching for Words.
okay, I was up all night programming a bunch of functions. The thing is, the given code im supposed to work with gave me a huge rode block and i just wasted hrs trying to use my prof's variables. So I just started writing functions using all new ptrs and variables and what have you, instesad of the ones already in the structures provided by the prof. You can kind of see what might cause trouble in the artist structure, because I have added char name[20]; and im using that instead of the artistName_P* deal. I figured I could just consolidate all of these new functions, variables and ptrs i made such as "initializenode" "find" and "insert" into "FindorInsertArtist" which is one of the given function that will be graded. was kind of looking for help on the consolidation part, if my new functions are even viable.
Currently when I compile I get two errors, probably just beacuse of the incompleteness, but its an ambiguous error to me:"undefined reference to findOrInsertArtist" "Undifined reference to InsertArtist"
Here is the updated program
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINEBUFFERSIZE 256
/* Definitions for data structure nodes (artist, disc, track) */
struct song {
char *songName_p;
int trackNumber;
struct song *nextSong_p;
};
struct disc {
char *discName_p;
int year;
struct song *song_p;
struct disc *nextDisc_p;
};
struct artist {
char name[20];
char *artistName_p;
struct disc *disc_p;
struct artist *nextArtist_p;
};
struct artist *end = (struct artist *) NULL; //NEW
struct artist *startPtr = (struct artist *) NULL; //NEW
struct artist *find(struct artist *, char * );//NEW
struct artist *initializenode(char *);//NEW
typedef struct artist artist_t;
typedef struct disc disc_t;
typedef struct song song_t;
typedef struct artist *artistNodePtr;
typedef struct disc *discNodePtr;
typedef struct song *songNodePtr;
/* function prototypes */
void InsertArtist(struct artist *New);
artistNodePtr findOrInsertArtist( artistNodePtr *sPtr, char *artistID );
discNodePtr findOrInsertDisc(discNodePtr *sPtr, char *discID, int releaseYear);
void findOrInsertSong(songNodePtr *sPtr, char *songID, int trackID);
void getNextLine(char buffer[], int bufferSize, FILE *fptr);
int main(int argc, char *argv[]) {
char name[20];
struct artist *ptr;
char lineBuffer[LINEBUFFERSIZE];
artistNodePtr startPtr = NULL; /* initially the artist list is empty */
FILE *musicFile;
char *artistTemp, *discTemp, *yearTemp, *trackTemp, *songTemp;
int year, track, menu;
artistNodePtr theArtist;
discNodePtr theDisc;
/* terminate program if command line argument for file name is missing */
if(argc==1) {
printf(" Must supply a file name as command line argument/n");
return 0;
}
/*Attempt to open the specified file for read access. If open fails, terminate program */
if((musicFile = fopen(argv[1], "r")) == NULL) {
printf ("Error opening music file. Program terminated/n");
return 0;
}
/* loop to read lines from the input file and create list structure */
getNextLine(lineBuffer, LINEBUFFERSIZE, musicFile);
while(!feof(musicFile)) {
/* Use the C strtok() function to break out the semicolon-separated */
/* fields of the input line which is in lineBuffer. */
/* Terminate the program is a problem is found with the format of */
/* the line. */
artistTemp = strtok(lineBuffer,";");
if (artistTemp == NULL) {
printf("Error parsing input file; Program is terminated\n");
return 0;
}
discTemp = strtok(NULL ,";");
if (discTemp == NULL) {
printf("Error parsing input file; Program is terminated\n");
return 0;
}
yearTemp = strtok(NULL ,";");
if (yearTemp == NULL) {
printf("Error parsing input file; Program is terminated\n");
return 0;
}
trackTemp = strtok(NULL ,";");
if (trackTemp == NULL) {
printf("Error parsing input file; Program is terminated\n");
return 0;
}
songTemp = strtok(NULL ,"\n");
if (songTemp == NULL) {
printf("Error parsing input file; Program is terminated\n");
return 0;
}
/* convert the year and track strings to integers using the C atoi() function */
year = atoi(yearTemp);
track = atoi(trackTemp);
/* Call the findOrInsertArtist(), findOrInsertDisc(), and findOrInsertSong() */
/* functions to place the song specified on this input line into the list. */
/* See the headers of these functions below for more information. */
theArtist = findOrInsertArtist(&startPtr, artistTemp);
theDisc = findOrInsertDisc(&(theArtist->disc_p), discTemp, year);
findOrInsertSong(&(theDisc->song_p), songTemp, track);
getNextLine(lineBuffer, LINEBUFFERSIZE, musicFile);
} /* end of while loop */
while(menu != 0) {
printf("1 to display entire catalog \n");
printf("2 to display alls songs by a given artist\n");
printf("3 to display all songs on a given disc\n");
printf("0 to exit the library\n ");
scanf("%d", &menu);
switch(menu) {
case 2: printf("enter an artist name");
scanf("%s", name);
ptr = find(startPtr, name);
if(ptr==NULL){
ptr = initializenode(name);
InsertArtist(ptr);
}
}
} /* end main */
}
struct artist *initializenode(char *name){ //NEW
artistNodePtr newNodePtr = (artistNodePtr)malloc(sizeof(name)};
if (newNodePtr != NULL) {
newNodePtr->artistName_p = (char*)malloc((strlen(name)+1)*sizeof(char));
if (newNodePtr->artistName_p != NULL) {
strcpy(newNodePtr->artistName_p, name);
}
newNodePtr->nextArtist_p = NULL;
newNodePtr->disc_p = NULL;
}
void InsertArtist(struct artist *New) { //NEW
struct artist *temp, *prev;
if(startPtr == NULL){
startPtr = New;
end = New;
startPtr->nextArtist_p = NULL;
return;
}
temp = startPtr;
while(strcmp(temp->name, New->name) < 0){
temp = temp->nextArtist_p;
if(temp == NULL)
break;
}
if(temp == startPtr) {
New->nextArtist_p = startPtr;
startPtr = New;
}
else{
prev = startPtr;
while(prev->nextArtist_p != temp){
prev = prev->nextArtist_p;
}
prev->nextArtist_p = New;
New-> nextArtist_p = temp;
if(end == prev)
end = New;
}
}
} /* end of function findOrInsertArtist() */
struct artist *find(struct artist *ptr, char *name){ //NEW
while (strcmp(name, ptr->name )!=0){
ptr = ptr->nextArtist_p;
if (ptr == NULL)
break;
}
return ptr;
}
discNodePtr findOrInsertDisc( discNodePtr *sPtr, char *discID, int releaseYear) {
} /* end of function findOrInsertDisc() */
void findOrInsertSong(songNodePtr *sPtr, char *songID, int trackID) {
} /* end of function findOrInsertSong() */
void getNextLine(char buffer[], int bufferSize, FILE *fptr) {
char temp;
int i = 0;
/*loop to read characters from file and place into buffer */
buffer[0] = fgetc(fptr);
while ( (!feof(fptr)) && (buffer[i] != '\n') && i<(bufferSize-1)) {
i = i +1;
buffer[i]=fgetc(fptr);
}
/* if loop terminated due to full buffer, purge the remaining characters up to
the next newline from the input stream */
if ((i == (bufferSize-1)) && (buffer[i] != '\n')) {
temp = fgetc(fptr);
while (temp != '\n') {
temp = fgetc(fptr);
}
}
/* Terminate the string with a null character */
buffer[i] = '\0';
} /* end of function getNextLine() */
//void printCatalog(artist_t *start_p);
//int printArtist(char *artist);
//printDisc(char *artist, char *disc);
Last edited by chucker; April 9th, 2012 at 12:03 PM.
-
April 9th, 2012, 12:18 PM
#20
Re: Structure Linked Lists: Searching for Words.
 Originally Posted by chucker
You can kind of see what might cause trouble in the artist structure, because I have added char name[20]; and im using that instead of the artistName_P* deal. I figured I could just consolidate all of these new functions, variables and ptrs i made such as "initializenode" "find" and "insert" into "FindorInsertArtist" which is one of the given function that will be graded. was kind of looking for help on the consolidation part, if my new functions are even viable.
You forgot another major part of this code, and that is the cleanup.
You call malloc(), but where do you properly destroy the linked list when you're done with it by calling free()? Right now, your main() function has memory leaks, and memory leaks are not acceptable, regardless if the code "runs".
Taking your code you posted, and compiling with the Comeau C++ compiler:
Thank you for testing your code with Comeau C/C++!
Tell others about http://www.comeaucomputing.com/tryitout !
Your Comeau C/C++ test results are as follows:
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions
"ComeauTest.c", line 128: warning: variable "menu" is used before its value is set
while(menu != 0) {
^
"ComeauTest.c", line 147: error: expected a ")"
artistNodePtr newNodePtr = (artistNodePtr)malloc(sizeof(name)};
^
"ComeauTest.c", line 147: error: expected a ";" (perhaps on the previous statement)
artistNodePtr newNodePtr = (artistNodePtr)malloc(sizeof(name)};
^
"ComeauTest.c", line 147: warning: missing return statement at end of non-void
function "initializenode"
artistNodePtr newNodePtr = (artistNodePtr)malloc(sizeof(name)};
^
"ComeauTest.c", line 147: error: extra ";" ignored,
In C: A function definition does not end with a semicolon
In C++: A non-member function definition, extern "C" block,
or namespace does not end with a semicolon
artistNodePtr newNodePtr = (artistNodePtr)malloc(sizeof(name)};
^
"ComeauTest.c", line 149: error: expected a declaration
Wild guess: Should this be in a function block?
if (newNodePtr != NULL) {
^
"ComeauTest.c", line 254: warning: parsing restarts here after previous syntax error
buffer[i] = '\0';
^
"ComeauTest.c", line 255: error: expected a declaration
Wild guess: Should this be in a function block?
} /* end of function getNextLine() */
^
At end of source: warning: parsing restarts here after previous syntax error
5 errors detected in the compilation of "ComeauTest.c".
In strict mode, with -tused, Compile failed
It would also help if you formatted the code a little better, plus remove those unnecessary commented out lines.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; April 9th, 2012 at 12:25 PM.
-
April 9th, 2012, 12:23 PM
#21
Re: Structure Linked Lists: Searching for Words.
Look carefully at the end of this line.
artistNodePtr newNodePtr = (artistNodePtr)malloc(sizeof(name)};
sizeof(name) isn't doing what you think it is.
I'm not a big fan of all these typedefs. If you want an artist pointer just declare one
artist* pArtist.
Likewise you don't need the casts here.
struct artist *end = (struct artist *) NULL;
Don't make things more complicated than they need to be.
Your style of indentation and matching braces doesn't have much logic to it. That's going to make your code harder to read and debug.
-
April 9th, 2012, 12:33 PM
#22
Re: Structure Linked Lists: Searching for Words.
 Originally Posted by chucker
Currently when I compile I get two errors, probably just beacuse of the incompleteness, but its an ambiguous error to me:"undefined reference to findOrInsertArtist" "Undifined reference to InsertArtist"
The reason why errors like this occur is poorly formatted code.
If you formatted your code properly, you would see that braces do not match in multiple places.
Regards,
Paul McKenzie
-
April 9th, 2012, 12:42 PM
#23
Re: Structure Linked Lists: Searching for Words.
This is for the sake of others, and to yourself:
Properly formatted:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINEBUFFERSIZE 256
/* Definitions for data structure nodes (artist, disc, track) */
struct song
{
char *songName_p;
int trackNumber;
struct song *nextSong_p;
};
struct disc
{
char *discName_p;
int year;
struct song *song_p;
struct disc *nextDisc_p;
};
struct artist
{
char name[20];
char *artistName_p;
struct disc *disc_p;
struct artist *nextArtist_p;
};
struct artist *end = (struct artist *) NULL; //NEW
struct artist *startPtr = (struct artist *) NULL; //NEW
struct artist *find(struct artist *, char * );//NEW
struct artist *initializenode(char *);//NEW
typedef struct artist artist_t;
typedef struct disc disc_t;
typedef struct song song_t;
typedef struct artist *artistNodePtr;
typedef struct disc *discNodePtr;
typedef struct song *songNodePtr;
/* function prototypes */
void InsertArtist(struct artist *New);
artistNodePtr findOrInsertArtist( artistNodePtr *sPtr, char *artistID );
discNodePtr findOrInsertDisc(discNodePtr *sPtr, char *discID, int releaseYear);
void findOrInsertSong(songNodePtr *sPtr, char *songID, int trackID);
void getNextLine(char buffer[], int bufferSize, FILE *fptr);
int main(int argc, char *argv[]) {
char name[20];
struct artist *ptr;
char lineBuffer[LINEBUFFERSIZE];
artistNodePtr startPtr = NULL; /* initially the artist list is empty */
FILE *musicFile;
char *artistTemp, *discTemp, *yearTemp, *trackTemp, *songTemp;
int year, track, menu;
artistNodePtr theArtist;
discNodePtr theDisc;
if (argc==1)
{
printf(" Must supply a file name as command line argument/n");
return 0;
}
if ((musicFile = fopen(argv[1], "r")) == NULL)
{
printf ("Error opening music file. Program terminated/n");
return 0;
}
getNextLine(lineBuffer, LINEBUFFERSIZE, musicFile);
while (!feof(musicFile))
{
artistTemp = strtok(lineBuffer,";");
if (artistTemp == NULL)
{
printf("Error parsing input file; Program is terminated\n");
return 0;
}
discTemp = strtok(NULL ,";");
if (discTemp == NULL)
{
printf("Error parsing input file; Program is terminated\n");
return 0;
}
yearTemp = strtok(NULL ,";");
if (yearTemp == NULL)
{
printf("Error parsing input file; Program is terminated\n");
return 0;
}
trackTemp = strtok(NULL ,";");
if (trackTemp == NULL)
{
printf("Error parsing input file; Program is terminated\n");
return 0;
}
songTemp = strtok(NULL ,"\n");
if (songTemp == NULL)
{
printf("Error parsing input file; Program is terminated\n");
return 0;
}
year = atoi(yearTemp);
track = atoi(trackTemp);
theArtist = findOrInsertArtist(&startPtr, artistTemp);
theDisc = findOrInsertDisc(&(theArtist->disc_p), discTemp, year);
findOrInsertSong(&(theDisc->song_p), songTemp, track);
getNextLine(lineBuffer, LINEBUFFERSIZE, musicFile);
} /* end of while loop */
while (menu != 0)
{
printf("1 to display entire catalog \n");
printf("2 to display alls songs by a given artist\n");
printf("3 to display all songs on a given disc\n");
printf("0 to exit the library\n ");
scanf("%d", &menu);
switch (menu)
{
case 2: printf("enter an artist name");
scanf("%s", name);
ptr = find(startPtr, name);
if (ptr==NULL)
{
ptr = initializenode(name);
InsertArtist(ptr);
}
}
} /* end main */
}
struct artist *initializenode(char *name)
{
artistNodePtr newNodePtr = (artistNodePtr)malloc(sizeof(name));
if (newNodePtr != NULL)
{
newNodePtr->artistName_p = (char*)malloc((strlen(name)+1)*sizeof(char));
if (newNodePtr->artistName_p != NULL)
{
strcpy(newNodePtr->artistName_p, name);
newNodePtr->nextArtist_p = NULL;
newNodePtr->disc_p = NULL;
}
}
}
void InsertArtist(struct artist *New)
{ //NEW
struct artist *temp, *prev;
if(startPtr == NULL)
{
startPtr = New;
end = New;
startPtr->nextArtist_p = NULL;
return;
}
temp = startPtr;
while(strcmp(temp->name, New->name) < 0)
{
temp = temp->nextArtist_p;
if(temp == NULL)
break;
}
if(temp == startPtr)
{
New->nextArtist_p = startPtr;
startPtr = New;
}
else
{
prev = startPtr;
while(prev->nextArtist_p != temp)
{
prev = prev->nextArtist_p;
}
prev->nextArtist_p = New;
New-> nextArtist_p = temp;
if(end == prev)
end = New;
}
}
struct artist *find(struct artist *ptr, char *name)
{ //NEW
while (strcmp(name, ptr->name )!=0)
{
ptr = ptr->nextArtist_p;
if (ptr == NULL)
break;
}
return ptr;
}
discNodePtr findOrInsertDisc( discNodePtr *sPtr, char *discID, int releaseYear)
{
}
void findOrInsertSong(songNodePtr *sPtr, char *songID, int trackID)
{
}
void getNextLine(char buffer[], int bufferSize, FILE *fptr)
{
char temp;
int i = 0;
buffer[0] = fgetc(fptr);
while ( (!feof(fptr)) && (buffer[i] != '\n') && i<(bufferSize-1))
{
i = i +1;
buffer[i]=fgetc(fptr);
}
if ((i == (bufferSize-1)) && (buffer[i] != '\n'))
{
temp = fgetc(fptr);
while (temp != '\n')
{
temp = fgetc(fptr);
}
}
buffer[i] = '\0';
}
Compiling this with Comeau C++:
Thank you for testing your code with Comeau C/C++!
Tell others about http://www.comeaucomputing.com/tryitout !
Your Comeau C/C++ test results are as follows:
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions
"ComeauTest.c", line 129: warning: variable "menu" is used before its value is set
while (menu != 0)
^
"ComeauTest.c", line 163: warning: missing return statement at end of non-void
function "initializenode"
}
^
"ComeauTest.c", line 218: warning: missing return statement at end of non-void
function "findOrInsertDisc"
}
The warnings here are very important. Plus the code that GCDEF pointed out must be fixed.
Regards,
Paul McKenzie
-
April 9th, 2012, 12:50 PM
#24
Re: Structure Linked Lists: Searching for Words.
Thanks a ton guys, and yeah GCDEF I am not a fan of the typedefs, but im stuck with them since they are required. Got some stuff to look at
-
April 9th, 2012, 12:53 PM
#25
Re: Structure Linked Lists: Searching for Words.
besides the indenting, you added brackets for me to reduce the errors?
-
April 9th, 2012, 01:22 PM
#26
Re: Structure Linked Lists: Searching for Words.
 Originally Posted by chucker
besides the indenting, you added brackets for me to reduce the errors?
Yes. You can't format code that has missing braces.
Regards,
Paul McKenzie
-
April 9th, 2012, 01:40 PM
#27
Re: Structure Linked Lists: Searching for Words.
 Originally Posted by Paul McKenzie
So where is your basic linked list code? The code to add, search, etc. I don't see any. That is the code you should be working on.
If you had that code, then this function you described above is very easy. Just call the functions that performs the actions you described:
Code:
artistNodePtr addName(const char *name)
{
artistNodePtr ptr = NULL;
ptr = findArtistName( name );
if ( !artistNodePtr )
artistNodePtr = insertNameInList( name );
return artistNodePtr;
}
But again, if the foundation doesn't work, then code such as above doesn't work.
Regards,
Paul McKenzie
at the moment with my useage of both char name and char artistID. I am sort of at loss at when to use which. Are they both necessary? I was jusst being a rebel initially making my own char name instead of using the given char artistID.
-
April 9th, 2012, 01:49 PM
#28
Re: Structure Linked Lists: Searching for Words.
 Originally Posted by chucker
at the moment with my useage of both char name and char artistID. I am sort of at loss at when to use which. Are they both necessary?
You have to find the name of an artist. That is the parameter that is being passed to that function.
You then search and return the node that matches the name. If not, you insert a new node using that name.
I was jusst being a rebel initially making my own char name instead of using the given char artistID.
Why would changing variable names makes a difference? What you are asked to do is straightforward.
Code:
artistNodePtr addName(const char *name)
{
artistNodePtr ptr = NULL;
ptr = findArtistName( name ); // find the artist with this name
if ( !ptr ) // does the artist exist?
ptr = insertNameInList( name ); // no, insert a new artist with this
// name and return the new artist that was created
return ptr; // return the artist
}
That is a correction to the code I posted.
Regards,
Paul McKenzie
-
April 9th, 2012, 02:25 PM
#29
Re: Structure Linked Lists: Searching for Words.
i should use my initialize funtion right? and then my insert one after i return the sptr?
Code:
artistNodePtr findOrInsertArtist( artistNodePtr *sPtr, char *name ) {
artistNodePtr sPtr = NULL;
sPtr = find(name);
if(!sPtr)
sPtr = initializenode(name);
return sPtr;
}
-
April 9th, 2012, 02:32 PM
#30
Re: Structure Linked Lists: Searching for Words.
 Originally Posted by chucker
i should use my initialize funtion right? and then my insert one after i return the sptr?
Code:
artistNodePtr findOrInsertArtist( artistNodePtr *sPtr, char *name ) {
artistNodePtr sPtr = NULL;
sPtr = find(name);
if(!sPtr)
sPtr = initializenode(name);
return sPtr;
}
I'd make find and insert two different functions. It doesn't look like your initialize function actually adds a node to the list. It creates it, but it appears to be sitting out there all by itself.
It looks to me like you're trying to do too much at once. Start with a function to add a node to the list. Test it. Add several nodes and make sure they're all connected properly.
Create and test your find function. Try it with nodes that do and don't exist. Make sure it works.
Call find. If it fails, call insert, but make sure each line of code or at least each function works as intended before moving on to the next one.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|