繁体   English   中英

字符串数组只保存最近的输入

[英]Array of Strings only saving the most recent input

我目前正在研究一个哈希表程序,但这不是问题,我有一个插入 function,但是当我运行它时,插入 function 只保存从 text.txt 文件中读取的最新字符串,如果该行是像“Finn 34”,它必须将 Finn 插入 hash 表中,值为 34,如果散列索引中已经有一些东西,它只会报告冲突,但是如果它是相同的字符串,例如“Finn 98”,它应该报告 Finn 已经在该索引中。 问题是每个字符串都指向来自 fscanf 的原始名称,我几乎可以肯定修复它的方法是使用 malloc,但每次我尝试使用它时,它都不起作用。

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

#define TableSize 45
#define Max 50
///// dont forget the edit in main

typedef struct node {
    char name[Max];
    int value;
} node;
node array[Max];


void init_array(){

    for (int i = 0; i < TableSize; i++){
      //array[i] = NULL;
    }
} 


void insert(int index, node *p){

  /*char * tempName = malloc (sizeof (char) * 50);
  strcpy(tempName, p->name);*/

  if (array[index].value != 0){
    //if (array[index]->name == p->name){
    if (strcmp(array[index].name, p->name) == 0){
      printf("Error %s already exists at index %d\n\n", array[index].name, index);
    }
    else{
      printf("Collision occured at index %d with\n\n", index);
    }
  }
  else{
    array[index] = *p;
    strcpy(array[index].name, p->name);
    printf("Stored %s with value of %d at index %d.\n\n", array[index].name, array[index].value, index);
  }

} 

void search(int index, char* name){
  printf("Found %s at index %d with a value of \n\n", name, index);
}

int hash(char name[Max]){
  int key = 0;
  for (int i = 0; name[i] != '\0'; ++i){
    char x = name[i];
    key = key + x;
  }
  key = key % TableSize;
  return key;
}

int main(int argc, char *argv[]) {
  init_array();
  FILE *fp;
  char ch;
  char name[Max];
  int x, HaValue;


  fp = fopen(argv[1], "r");
  if (NULL == fp) {
        //printf("file can't be opened \n");
        fp = fopen("text.txt", "r"); ///////get rid of when done
    }
  node * p;  
  p = malloc(sizeof(struct node));
 do{
  x = 0;

  int counter = 0;
  if (fscanf(fp, "%49s", name) != 1) break;
  if (fscanf(fp, "%d", &x) != 1) counter = 1;
  HaValue = hash(name);
  p->value = x;
  strcpy(p->name, name);
  if (counter != 0) {
    search(HaValue, name);
  }
  else{
    insert(HaValue, &p);
  }
  
  } while(!feof(fp));

  printf("%d %s %d", 12, array[12].name, array[12].value);
  //test to see if the name was correctly saved. should be "12 Dog 12"

  
    // Closing the file
    fclose(fp);
  
  return 0;
}

这是 text.txt 文件

Brom 89
Paul 25
Jake 34
Yokai 45
Jake
Dog 20
Paul 30
Brom
Kron 40
Finn 234
OOO 13
Jim 555
Bruh 23
Bruh
Corn
Freddy 40
Freddy

我可以看到一个用 static 存储持续时间( array )声明的数组,作为固定数量的节点指针。 您稍后声明要使用自动存储持续时间指向的节点,这是您的错误发生的地方,因为节点被有效地销毁,然后在函数返回时“在堆栈上”被践踏。

我建议您将array更改为node数组。

typedef struct node {
    char name[Max];
    int value;
} node;
node array[Max];

当您使用 static 存储持续时间(函数外部)声明此数组时,您不需要初始化它; 它开始归零。 您也不需要NULL检查类似array[index] != NULL来检查它是否已被分配,您可以直接跳到使用strcmp来验证结果,或者只检查第一个字符以查看它是否非零...

 array[index] = p;

您还可以将p声明为struct node而不是struct node * ,并且此分配是有意义的,或者您可以将其更改为: array[index] = *p; 例如。

malloc而言,知道如何使用它很好,但 memory 分配是我更愿意与数据结构和算法分开的一课,我认为这是一个数据结构和算法难题。 关于这一点,最好避免对malloc进行不必要的调用,这样可以选择更合适的存储持续时间,并且这种设计适用于某些情况(就像mallocrealloc会在您开发更复杂的哈希表时变得更晚)所以它是完美的在我看来,保持简单。

我看到另一个问题,即其中一些输入行没有关联的十进制数字值,并且您的fscanf错误处理代码不完整且有些误导。 让我们介绍一下我注意到的那些例子:

if (fscanf(fp, "%s", name) == 3){}

我不知道当fscanf成功(或失败,就此而言,或者原因和方式,我们将很快介绍)时你期望发生什么,但假设它只写入一个变量( name ,在这种情况下)它应该返回 1。我更喜欢以缩进形式处理错误,因此程序沿着成功路径相对不缩进,所以我会写如下内容:

if (fscanf(fp, "%49s", name) != 1) break;

我假设您可以在这里安全地中断循环,因为如果您无法读取一个单词,则fp位于文件末尾或某些 state 错误中。

if (fscanf(fp, "%d", &x) == 3){}

现在我们来看看fscanf的毛茸茸的部分,看看......我们已经讨论了一种失败模式(feof/error 位),但没有讨论另一种:匹配失败。 当您尝试读取十进制数字 integer 序列但没有序列时,如上所述,返回值将为正数,但与您期望分配的字段数不同。 在这种情况下,期望为 1,但fscanf返回 0,因此:

switch (fscanf(fd, "%d", &x)) {
    case 0: // fscanf didn't assign to x, which means match failure occured...
            x = 0; // in this case I'll just zero x so we're not using stale data
    case 1: break; // ... this is where control flows when x is assigned to successfully
    default: if (!feof(fp)) {
            fputs("This is not good, because it means the stream is in state of error\n", stderr);
            exit(EXIT_FAILURE);
             }
}

暂无
暂无

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

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