简体   繁体   English

while 循环中的 scanf 不断修改数组的先前值

[英]scanf inside while loop keeps modifieing array's previous values

I'm trying to implement a hash table in C so the idea is simple:我正在尝试在 C 中实现一个 hash 表,所以这个想法很简单:

1- the user enters a string 2- the program adds it to the table 3- prints the whole table 1- 用户输入一个字符串 2- 程序将其添加到表中 3- 打印整个表

but I noticed that the program replaces all previous values with the new one:!但我注意到该程序用新值替换了所有以前的值:! THE CODE:代码:


//edit
//initialize array to empty string
void init(char* table[]){
    for (int i=0; i<T_LEN; i++){
        table[i] = "";
    }
}

int hash(char* str){
    int result = 0;
    for (int i=0; i<sizeof(str); i++){
        result += str[i]; 
    }
    return result % T_LEN;
}

void add(char* table[]){
    char* input;
    printf("> ");
    scanf("%s", (char*)&input);
    int index = hash((char*)&input);
    table[index] = (char*)&input;
    return;
}

int main(){
    char* hash_table[T_LEN];
    init(hash_table);
    while(1){
        add(hash_table);
        print_table(hash_table);
    }
    return 0;
}

RESULT:结果:

> abc
1         -------
2         -------
3         -------
4         -------
5         abc
6         -------
7         -------
8         -------
9         -------
10        -------
> esd
1         -------
2         -------
3         -------
4         -------
5         esd
6         -------
7         esd
8         -------
9         -------
10        -------
> ee
1         -------
2         -------
3         ee
4         -------
5         ee
6         -------
7         ee
8         -------
9         -------
10        -------

EDIT: the site says "It looks like your post is mostly code; please add some more details."编辑:该网站说“看起来您的帖子主要是代码;请添加更多详细信息。” so here I'm:D所以我在这里:D

some problems with your code:您的代码存在一些问题:

  1. return; at the end of the function called add is redundant which means that it has no meaning as in all the cases the function will end at this point在 function 的末尾称为add是多余的,这意味着它没有任何意义,因为在所有情况下 function 将在此时结束

  1. the compiler is giving the warning while(1) in the main as you don't return from the function, so you can do编译器在main中发出警告while(1)因为你没有从 function 返回,所以你可以这样做

    int __attribute__((noreturn)) main()

to tell the compiler that the main will never return告诉编译器main永远不会返回


  1. in the function called init , as you are declaring an array of pointers, then it's better to write:在 function 调用init ,因为你正在声明一个指针数组,那么最好写:

     table[i] = malloc(sizeof(char) * MAX_NAME_LEN); table[i][0] = '\0';

instead of:代替:

 table[i] = "";

to reserve memory in heap for the string not in the read-only memory.堆中为不在只读memory 中的字符串保留 memory。


  1. in the lines:在行中:

     scanf("%s", (char*)&input); int index = hash((char*)&input);

the pointer called input is already of type char* , so you don't have to cast it as it's not a better practice to cast everything, also you should reserve a space for the input variable in the heap memory like:称为input的指针已经是char*类型,因此您不必强制转换它,因为强制转换所有内容并不是更好的做法,您还应该在堆 memory 中为input变量保留一个空间,例如:

   char* input = malloc(sizeof(char) * MAX_NAME_LEN);  

and so your code becomes:所以你的代码变成:

    char* input = malloc(sizeof(char) * MAX_NAME_LEN);
    printf("> ");
    scanf("%s", input);
    int index = hash(input);
    table[index] = input;

  1. instead of sizeof() in the line:而不是行中的sizeof()

     for (int i=0; i<sizeof(str); i++)

I think you should use strlen instead like:我认为你应该使用strlen而不是:

for (int i=0; i<strlen(str); i++)

as sizeof(str) = 4 as sizeof(pointer) = 4 as the pointers has fixed size as sizeof(str) = 4 as sizeof(pointer) = 4因为指针具有固定大小


with all this being said, this is the edited code:综上所述,这是编辑后的代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define T_LEN 10
#define MAX_NAME_LEN    20

void print_table(char* table[])
{
    for (int i = 0; i < T_LEN; ++i) {
        printf("%d\t\t%s\n",i, table[i]);
    }
}

//edit
//initialize array to empty string
void init(char* table[]){
    for (int i=0; i<T_LEN; i++){
        table[i] = malloc(sizeof(char) * MAX_NAME_LEN);
        table[i][0] = '\0';
    }
}

int hash(char* str){
    int result = 0;
    for (int i=0; i<strlen(str); i++){
        result += str[i];
    }
    return result % T_LEN;
}

void add(char* table[]){
    char* input = malloc(sizeof(char) * MAX_NAME_LEN);
    printf("> ");
    scanf("%s", input);
    int index = hash(input);
    table[index] = input;
}

int __attribute__((noreturn)) main(){
    char* hash_table[T_LEN];
    init(hash_table);
    while(1){
        add(hash_table);
        print_table(hash_table);
    }
}

and this is some output:这是一些 output:

>abc
0
1
2
3
4               abc
5
6
7
8
9
>esd
0
1
2
3
4               abc
5
6               esd
7
8
9
>ee
0
1
2               ee
3
4               abc
5
6               esd
7
8
9
>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM