簡體   English   中英

while 循環中的 scanf 不斷修改數組的先前值

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

我正在嘗試在 C 中實現一個 hash 表,所以這個想法很簡單:

1- 用戶輸入一個字符串 2- 程序將其添加到表中 3- 打印整個表

但我注意到該程序用新值替換了所有以前的值:! 代碼:


//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;
}

結果:

> 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        -------

編輯:該網站說“看起來您的帖子主要是代碼;請添加更多詳細信息。” 所以我在這里:D

您的代碼存在一些問題:

  1. return; 在 function 的末尾稱為add是多余的,這意味着它沒有任何意義,因為在所有情況下 function 將在此時結束

  1. 編譯器在main中發出警告while(1)因為你沒有從 function 返回,所以你可以這樣做

    int __attribute__((noreturn)) main()

告訴編譯器main永遠不會返回


  1. 在 function 調用init ,因為你正在聲明一個指針數組,那么最好寫:

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

代替:

 table[i] = "";

堆中為不在只讀memory 中的字符串保留 memory。


  1. 在行中:

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

稱為input的指針已經是char*類型,因此您不必強制轉換它,因為強制轉換所有內容並不是更好的做法,您還應該在堆 memory 中為input變量保留一個空間,例如:

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

所以你的代碼變成:

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

  1. 而不是行中的sizeof()

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

我認為你應該使用strlen而不是:

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

as sizeof(str) = 4 as sizeof(pointer) = 4因為指針具有固定大小


綜上所述,這是編輯后的代碼:

#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);
    }
}

這是一些 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