这是一个简单程序的开始,该程序将用户条目存储在哈希表中。它仍然是非常基本的(还没有添加链接列表来处理冲突,哈希函数非常简单,是更强大的临时占位符,我还没有处理释放所有malloc的内存,等等),但是我想先了解一下基本功能,然后再继续。
在此版本中,我的最新条目似乎覆盖了以前的条目。看起来这些条目仍在正确的位置(由哈希函数决定),但是不知何故,最后一个是放置在各处的条目。
对不起,我知道很多代码,但是我不确定如何创建此代码的较小版本来隔离问题:
exports.encomenda_create = function (req, res, next) {
我确定此代码还有其他问题,我很感谢任何人愿意在此处提供的其他建议。例如,我总是想知道代码的哪些部分需要自己的功能,哪些应该/可以组合在一起。似乎其中的一些内容应该分开,但是在弄清楚如何正确地将信息从一个函数传递给另一个函数时,我遇到了很多麻烦。
更新#1 (在一些评论之后):
是的,现在可以使用!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUF_SIZE_WORDS 4096
#define BUF_SIZE_NUMBERS 256
#define MAX_WORDS 10
typedef struct tablestruct
{
int val;
char* text;
struct tablestruct *next;
}
table;
// declare the hashing function that takes in the string to be hashed and the length of it
unsigned int hash(char *str, int length);
// // declare a linked list creation function
// lnode *createnode(char *str, htnode *hashtable);
// declare a hash table printing function
void print_ht(table *array[MAX_WORDS]);
int number_input();
int word_input(int num_words, table *array[MAX_WORDS]);
void empty_stdin();
int main(void)
{
// call number_input() to ask user for number of words they'd like to store, save that in word_count
int word_count = number_input();
// create hash table
table *array[MAX_WORDS];
for (int j = 0; j < MAX_WORDS; j++)
{
array[j] = malloc(sizeof(table));
array[j]->val = j;
}
// add some kind of a memory check?
// PUT word_input inside the if statement to make sure it worked?
// call word_input() and store the result in success
int success = word_input(word_count, array);
// if not successful:
if (!success)
{
fputs ("some kind of problem with word_input\n", stderr);
return 1;
}
// printf("\ncurrent address of the hash table: %p\n", &array[0]);
printf("printing hash table: \n");
print_ht(array);
// REMEMBER TO FREE WHATEVER'S MALLOC'ED
}
int number_input(void)
{
// a bunch of code is borrowed from David's answer here: https://stackoverflow.com/questions/52920852/why-is-the-following-code-not-allowing-me-to-get-user-input-with-fgets-yet-works?noredirect=1#comment92940817_52920852
int num_words = 0, /* number of words to enter */
word_count_check = 0; /* word count */
char buffer[BUF_SIZE_NUMBERS] = ""; /* buffer of sufficient size for input */
for (;;) /* loop continually until valid input of NUMBER OF WORDS USER WANTS TO ENTER or user cancels */
{
printf ("how many words would you like to enter? [1-%d]: ", MAX_WORDS);
// check for cancellation of input
if (!fgets (buffer, BUF_SIZE_NUMBERS, stdin))
{
fputs ("user canceled input\n", stderr);
return 1;
}
// check if user simply hit enter w/o typing anything
if(buffer[0] == '\n')
{
printf("please enter a value\n");
continue;
}
size_t inlength = strlen(buffer);
if (inlength && buffer[inlength - 1] == '\n')
{
// printf("hurray!\n");
buffer[--inlength] = 0;
}
else if (inlength == BUF_SIZE_NUMBERS - 1) /* the line was too long */
{
printf("you've entered too many characters... please stick to a maximum of %i\n", BUF_SIZE_NUMBERS);
empty_stdin();
// continue;
}
// make sure user actually entered a proper int
if (sscanf (buffer, "%d", &num_words) != 1) /* sscanf is used for conversion */
{
fputs ("invalid conversion to int; please provide valid input\n", stderr);
continue;
}
// check if the number entered is out of range
if (num_words < 1 || num_words > MAX_WORDS)
fprintf (stderr, "%2d out of valid range.\n", num_words);
else
break; /*if the input has been validated, we can now break out of the for loop */
}
return(num_words);
}
int word_input(int num_words, table *array[MAX_WORDS])
{
int word_count = 0;
for(;;) /* loop until word_count == num_words is achieved */
{
// declare an array for storing input string
char buffer[BUF_SIZE_WORDS];
char valid_input[BUF_SIZE_WORDS];
// prompt user for input
printf("\nplease enter a string: ");
// get input and check for CTRL+D
if (!fgets(buffer, BUF_SIZE_WORDS, stdin))
{
fputs ("user canceled input\n", stderr);
exit(1);
}
// check if user simply hit enter w/o typing anything
if(buffer[0] == '\n')
{
printf("please enter a word that's more than 0 characters\n");
// empty_stdin();
continue;
}
size_t inlength = strlen(buffer);
if (inlength && buffer[inlength - 1] == '\n')
{
buffer[--inlength] = 0;
// get rid of trailing spaces using sscanf
sscanf(buffer, "%s", valid_input);
inlength = strlen(valid_input);
printf("string length: %zu\n", inlength);
// call the hash function to get the hash code
int result = hash(&valid_input[0], inlength);
table *newnode = malloc(sizeof(table));
// store the current string in the newnode->text
newnode->text = valid_input;
// strcpy(newnode->text, valid_input); ??
// newnode->val = inlength;
// confirm string has been stored
printf("you've entered: %s\n", newnode->text);
// attach the node to correct slot in the hash table -- ADD LINKED LIST FUNCTIONALITY HERE TO DEAL WITH COLLISIONS!
array[result]->next = newnode;
// printf("address of the current HT entry is: %p\n", newnode);
// increment word count
word_count++;
printf("word_count = %i\n", word_count);
if (word_count == num_words)
{
printf("\nDONE!\n\n");
return word_count;
}
}
// check if the user entered too many characters
else if (inlength == BUF_SIZE_WORDS - 1) /* the line was too long */
{
printf("you've entered too many characters... please stick to a maximum of %i\n", BUF_SIZE_WORDS);
empty_stdin();
}
}
// return word_count;
}
/* helper function to remove any chars left in input buffer */
void empty_stdin()
{
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
// THIS HASH FUNCTION IS TOO BASIC AND NEEDS TO BE REPLACED WITH SOMETHING BETTER
unsigned int hash(char *str, int length)
{
int sum = 0;
for (int j = 0; j < length; j++)
{
sum += str[j];
}
printf("here's what the hashing function is returning: %i\n", (sum % MAX_WORDS));
return sum % MAX_WORDS;
}
void print_ht(table *array[MAX_WORDS])
{
// printf("address of the hash table inside print function: %p\n\n", array);
table *cursor = malloc(sizeof(table));
// add memory check
for (int i = 0; i < MAX_WORDS; i++)
{
printf("[%i] -> ", i);
cursor = array[i];
if (cursor->next)
{
table *temp = malloc(sizeof(table));
temp = cursor->next;
printf("%s\n", temp->text);
free(temp);
}
else
{
printf("empty\n");
}
}
free(cursor);
}
答案 0 :(得分:1)
您正在为每个节点设置newnode->text = valid_input;
。但是valid_input
是在word_input
的for循环范围内声明的本地缓冲区。因此,这不是有效的代码-不能保证该函数之外还存在缓冲区。
实际上,valid_input
包含一些堆栈存储器的地址,每次进入此函数时都会重复使用该地址,因此所有node->text
指针最终都指向包含最后一个值的同一存储器输入。
通过打印所有节点的文本指针的值,您应该能够验证这种情况。
您需要为要保存的每个条目创建一个新缓冲区。