我有一个格式为: [name][number][amount] number 的文件作为字符串。我在 strcmp 中使用它。问题是我遇到了分段错误。我知道在大多数情况下,当 strcmp 标记分段错误时,这意味着参数之一为空或找不到它的“结束”('\0')。我检查了 gdb,我不能说这是否是问题。看看:
> (gdb) bt full
> #0 0x08048729 in lookup (hashtable=0x804b008, hashval=27,
> number=0x804b740 "6900101001")
> list = 0xffffffff
> #1 0x080487ac in add (hashtable=0x804b008,
> number=0x804b740 "9900101001", name=0x804b730 "Smithpolow",
> time=6943)
> new_elem = 0xffffffff
> hashval = 27
> #2 0x08048b25 in main (argc=1, argv=0xbffff4b4)
> number = 0x804b740 "9900101001"
> name = 0x804b730 "Smithpolow"
> time = 6943
> i = 2
代码:
typedef struct HashTable
{
int length;
struct List *head;
} HashTable;
//(resolving collisions using chaining)
typedef struct List
{
char *number;
char *name;
int time;
struct List *next;
} List;
int primes[]={17,29,51,79,163,331,673,1361,2729,5471,10949,21911,43853,87719,175447,350899};
*int PrimesIndex=1;* **int PrimesIndex=0;** **//changed.**
HashTable *createHashTable(size)
{
HashTable *new_table = malloc(sizeof(*new_table)*size);
if (new_table == NULL)
{ return NULL;
}
int i=0;
for(i; i<size; i++)
{ new_table[i].length=0;
new_table[i].head=NULL;
}
return new_table;
}
int hash ( HashTable *hashtable,char* number)
{
int hashval = 0;
int i = 0;
for ( i = 0; i < 10; i++)
{ hashval = (hashval << 5)|(hashval >> 27);
hashval += ( int)number[i];
}
return hashval % primes[PrimesIndex];
}
List *lookup ( HashTable *hashtable,int hashval,char number[10])
{
printf("NUMBER:%s\n",number);
List *list=hashtable[hashval].head;
for(list; list!=NULL; list=list->next){
if (strcmp(number,list->number)==0)
return list;
}
return NULL;
}
int add ( HashTable* hashtable,char number[10],char* name,int time)
{
List *new_elem;
int hashval=hash (hashtable,number);
new_elem=hashtable[hashval].head;
if(hashtable[hashval].length>0)
{
if ((lookup (hashtable,hashval,number))!=NULL) {return 0;}
}
if (!(new_elem=malloc(sizeof(struct List)))){ return -1;}
//insert values for the new elem
new_elem->number=strdup(number);
new_elem->name=strdup(name);
new_elem->time=time;
hashtable[hashval].head=new_elem;
new_elem->next=NULL;
hashtable[hashval].length++;
/* rehash existing entries if necessary */
if(hashTableSize(hashtable)>= 2*primes[PrimesIndex])
{
hashtable = expand(hashtable);
if (hashtable ==NULL){
return 0;
}
}
return 1;
}
HashTable* expand( HashTable* h )
{ printf("EXPAND \n");
HashTable* new;
List *temp;
int n;
List *node,*next;
PrimesIndex++;
int new_size= primes[PrimesIndex]; /* double the size,odd length */
if (!(new=malloc((sizeof( List*))*new_size))) return NULL;
for(n=0; n< h->length; ++n) {
for(node=h[n].head; node; node=next) {
add (new, node->number, node->name,node->time);
next=node->next;
//free(node);
}
}
free(h);
return new;
}
和主要的:
int main(int argc, char *argv[])
{
char **token;
FILE *delimitedFile;
/*Here's an example of tokenizing lines from an actual file*/
/*Open file for reading ("r"), and take a FILE pointer,
which you can use to fetch lines using fgets()*/
my_hash_table = createHashTable(17);
if(my_hash_table==NULL)
{ return 1;
}
FILE * File2;
if ( ( File2=fopen(" File.txt","r")) !=NULL )
{ // File.txt format: [name number time]
int li = 0;
char *lin = (char *) malloc(MAX_LINE * sizeof(char));
while(fgets(lin, MAX_LINE, File2) != NULL)
{
token = my_linetok(lin, " ");
if(token != NULL)
{
char* number ;
char* name;
int time;
int i;
for(i = 0; token[i] != NULL; i++)
{
name=strdup(token[0]);
number=strdup(token[1]);
time=atoi(token[2]);
if (i==2)
{ int insertDone=0;
insertDone =add(my_hash_table,number,name,time);
}
}
free(name);
free(number);
free(token);
}
else
{
printf("Error reading line %s\n", lin);
exit(1);
}
}
}
else
{
printf("Error opening file \nEXIT!");
exit(0);
}
return 1;
}