GIDForums  

Go Back   GIDForums > Computer Programming Forums > C Programming Language
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 24-Jul-2005, 11:12
penance penance is offline
New Member
 
Join Date: Jul 2005
Posts: 14
penance is on a distinguished road

Hash table problem.


Hi, I'm sorry to trouble anyone, but I've been writing a C program for a hash table that uses an array of linked lists to retrieve commands from an outside input file, carry them out, and print the result to an outside output file. The program I've completed compiles well enough but it doesn't run correctly. It pauses for a while, then it says it encountered an error and has to close, but it doesn't specify what the problem is. I tried to use Visual C++'s debugger to solve the problem, and what it says is "Unhandled exception in program.exe: 0xC0000005: Access Violation." It then points to this line of code:
strarray[index] = addnode(strarray[index], item, strarray[index]->refcount);. I have no idea what's wrong with it and the debugger is like a foreign language to me, so if anyone could maybe help me figure this out, that would be much appreciated.

This is the code for the program.

CPP / C++ / C Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#define MAXSTRING 100
/*Create linked list node structure.*/

struct node {
	char name[MAXSTRING];
	int refcount;
	struct node *next;
};

int calcindex(char j[100]);
struct node * addnode(struct node *j, char k[100], int l);
int lookup(char j[100], struct node *k);
void changeref(char j[100], struct node *k);
void print(struct node *j, FILE *k);

int main(void)
{
	/*Necessary variables.*/
	FILE *ifp, *ofp;
	char item[MAXSTRING];
	char command[MAXSTRING];
	int index;
	int search;
	int i;

	/*Create array[19] of these nodes.*/
	struct node * strarray[19] = {0};
	/*Open input file.*/
	ifp = fopen("inputfile.txt", "r");
	/*Open output file*/
	ofp = fopen("outputfile.txt", "w");
	/*Do until command equals end of input file.*/
	while (fscanf(ifp, "%s", &command) != EOF) {
		/*Get string from file.*/
		fscanf(ifp, "%s", &item);
		/*Print command and string to output file.*/
		fprintf(ofp, "%s	%s", command, item);
		/*Check to see if command is Dec or Use.*/
		/*If the command is Dec:*/
		if (strcmp(command, "DEC") == 0) {
			/*Use calculate index function.*/
			index = calcindex(item);
			/*Check indexed linked list for name by searching list at specific index*/
			search = lookup(item, strarray[index]);
			/*If name exists in list*/
			if (search == 1){
				/*Print error message "***Duplicate Name***" to output file*/
				fprintf(ofp, "	***Duplicate Name***");
				/*Start a new line.*/
				fprintf(ofp, "\n");
			}
			/*If name does not exist in list*/
			else {
				/*Use add node function with proper name, reference count, and pointer.*/
				strarray[index] = addnode(strarray[index], item, strarray[index]->refcount);
				/*Start new line on output file.*/
				fprintf(ofp, "\n");
			}
		}
		/*If the command is Use:*/
		else {
			/*Use calculate index function.*/
			index = calcindex(item);
			/*Check indexed linked list for name by searching list at specific index*/
			search = lookup(item, strarray[index]);
			/*If name exists in list*/
			if (search == 1) {
				/*Reference count +1*/
				changeref(item, strarray[index]);
				/*Start new line on output file.*/
				fprintf(ofp, "\n");
			}
			/*If name does not exist in list*/
			else {
				/*Print error message "***Undefined Name***" to output file*/ 
				fprintf(ofp, "	***Undefined Name***");
				/*Start a new line.*/
				fprintf(ofp, "\n");
			}
		}
	}
	/*Cycle through array.*/
	for (i = 0; i < 19; i++) {
		/*If current linked list is empty*/
		if (strarray[i] == NULL) {
			/*Continue*/
			continue;
		}
		/*If current linked list has data*/
		else {
			/*Print current array field.*/
			fprintf(ofp, "%d	", i);
			/*Use print function*/
			print(strarray[i], ofp);
		}
	}
	/*Close input file.*/
	fclose(ifp);
	/*Close output file.*/
	fclose(ofp);
	/*End program.*/
	return 0;
}

int calcindex(char value[]) {
	int total = 0;
	size_t i;
	/*Until the end of the string*/
	for (i=0; i<strlen(value); i++) {
		/*If current character is a letter*/
		if (isalpha(value[i])) {
			/*If current character is uppercase*/
			if (isupper(value[i])) {
				/*Add to total this value*/
				total = value[i] - 'A' + 1;
			}
			/*If current character is lowercase*/
			else {
				/*Add to total this value*/
				total = value[i] - 'a' + 1;
			}
		}
		/*If current character is a number*/
		else {
			/*Add to total this value*/
			total = value[i] - '0';
		}
	}
	/*Return total*/
	return total;
}

struct node * addnode(struct node *list, char n[], int rc) {
	struct node *pNew = NULL;
	struct node *created_list = NULL;
	/*Creating default node*/
	pNew = malloc(sizeof(struct node));
	strcpy(pNew->name, n);
	pNew->refcount = rc;
	pNew->next = NULL;
	/*If new node is first node in list*/
	created_list = list;
	if (list == NULL)
		return pNew;
	/*If otherwise*/
	while (list->next != NULL)
		list = list->next;
	list->next = pNew;
	/*Return updated list*/
	return created_list;
}

int lookup(char value[], struct node *head) {
	/*If list node is empty, return 0*/
	if (head == NULL)
		return 0;
	/*If list node contains the value, return 1*/
	else if (strcmp(value, head->name) == 0)
		return 1;
	/*Otherwise continue down the list*/
	else
		return(lookup(value, head->next));
}

void changeref(char value[], struct node *head) {
	int rc;
	/*If list node contains the value, raise reference count by 1*/
	if (strcmp(value, head->name) == 0) {
		rc = head->refcount;
		rc += 1;
		head->refcount = rc;
	}
	/*Otherwise continue down the list*/
	else {
		changeref(value, head->next);
	}
}

void print(struct node *list, FILE *ofp) {
	struct node *current = list;
	/*While current node is not empty*/
	while (current != NULL)
	{
		/*Print out the node information*/
		fprintf(ofp, "	%s	%d\n", current->name, current->refcount);
		/*Continue to the next node*/
		current = current->next;
	}
}

The input file is a Notepad file with this text:
Code:
DEC COP3502 DEC SCHOOL USE COP3502 DEC SCHOOL DEC AA12 USE PEN USE COP3502
The output file is an empty Notepad file.

Thanks again for any help anyone can provide.
Last edited by dsmith : 24-Jul-2005 at 12:44. Reason: Please use [c] && [/c] for C code syntax
  #2  
Old 24-Jul-2005, 19:50
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,791
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold
Quote:
Originally Posted by penance
Hi,
..
..
. I have no idea what's wrong with it and the debugger is like a foreign language to me, so if anyone could maybe help me figure this out, that would be much appreciated.
This type of crash typically happens when the program is trying to access some memory that doesn't belong to it.

Since the program compiles OK, make the program tell you what's wrong. Debuggers are marvelous tools, but the best debugging tool is the little gray cells that you already know how to use.

OK, I will help a little:

these are wrong:
CPP / C++ / C Code:
.
    fscanf(ifp, "%s", &command)

    fscanf(ifp, "%s", &item);

command and item are arrays of char. When you use the name of an array (without any []) it is treated as a pointer to char. Therefore the scanf arguments should be changed to looksomething like this:

CPP / C++ / C Code:
.
  fscanf(ifp, "%s", command)
  
  fscanf(ifp, "%s", item);

I recommend that you check the return value of scanf functions every time you call them, so, maybe the program starts like this:

CPP / C++ / C Code:
.
  ifp = fopen("inputfile.txt", "r");
  if (!ifp) {
    printf("Can't open input file\n");
    return 0;
  }
  printf("opened input file\n");

  ofp = fopen("outputfile.txt", "w");
  if (!ofp) {
    printf("Can't open output file\n");
    return 0;
  }
  printf("opened output file\n");

  while (fscanf(ifp, "%s", command) == 1) {
    printf("command = %s\n", command);

    if (fscanf(ifp, "%s", item) != 1) {
      printf("fscanf failed for item\n");
      break;
    }
    printf("item = %s\n", item);


Get the idea? Make the program tell you everything that it does. You can take out the extra printf() statments later (or make comments out of them), so that the screen is not cluttered. (Also check the return values of other system functions, like fopen().)

Now, if you proceed in this manner, and if the files opened OK, you will probably get a program crash somewhere along the line, after some print statement that tells you how far you got.


Maybe there are other bugs, and maybe not, but you can make the program tell you what it's doing at each step and if it's not what you had in mind: you can see where you need to fix it.

Regards,

Dave
Last edited by davekw7x : 24-Jul-2005 at 20:50.
 
 

Recent GIDBlogWriting a book by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Graphic problem in Unreal Tournament 2004 zerox Computer Software Forum - Games 10 09-Oct-2005 13:31
Hash Table & Graph Kay Chan C++ Forum 7 08-Oct-2004 08:44
C I/O problem kelly80 C Programming Language 4 27-Apr-2004 21:15
customizing preprocessor and hash table incognito54 C Programming Language 2 21-Apr-2004 19:25
[Tutorial] MySQL Basics nniehoff MySQL / PHP Forum 15 23-Mar-2003 20:42

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 09:22.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.