C++ 程序结束而不是重复 For 循环

标签 c++ for-loop crash

我正在为类分配编写一个程序,该程序使用 3 个不同的双哈希函数(例如 1/1、1/2、1/3、2/1、2/2 等)测试 3 个哈希函数,并且最终目标是按照我教授的指示,通过控制台命令“exename > Results.txt”将每个配对的测试结果输出到文件中。我即将进行最终测试,但我的程序将进入 main,完成一次嵌套的 for 循环,输出第一个哈希函数配对的测试结果,然后程序结束,没有错误。我已经把 Visual Studio 12 的调试器弄乱了好几个小时,但与刚开始时相比,我并没有更接近找到解决方案。当我通过控制台运行程序时,它输出“无法打开数据文件。程序终止”,即使在单步执行程序时它从未进入该 for 循环。有任何想法吗?谢谢!

附注我知道该程序中使用的某些方法可能是非常规的,或者不一定是实现此目的的最简单/最佳方法,但我必须遵守教授的标准。

更新:我在 getline for 循环中添加了一条 cout 行,现在可以看到测试完成一次,然后下一次重复该 for 循环 41 次并退出,而不是完成全部 50 次。看起来我们是到达某个地方。

这是我的输出:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950ERROR1 Testing hash function 1 using double hash 1. Total collisions = 360. |||||||-------------------------------------|||||||||||||||-----|||||||||||||||--------|||||||||||||

1234567891011121314151617181920212223242526272829303132333435363738394041

#include <iostream>
#include <iomanip>
#include <fstream>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <string.h>

#define TABLESIZE     100
#define KEYSIZE       4
#define EMPTYKEY      "----"
#define DATAFILE      "P4DATA.txt"

using namespace std;

struct HashStruct
{
     char key[5];
     int data;
};

void InitTable(HashStruct hashT[], int TableSize);
int Hash_1(char *key);
int Hash_2(char *key);
int Hash_3(char *key);
int ProbeDec_1(char *key);
int ProbeDec_2(char *key);
int ProbeDec_3(char *key);
int HashInsert(HashStruct T[], char *key, int data, int hNum, int dhNum);

int main(void){

     int          hashNum, dHashNum, count;
     ifstream     *inFile;
     HashStruct   T[100];  // Hash table srray of 100 data structures
     char         line[64];// Array to hold lines read from file
     char         key[5];  // Array to hold 4-character keys
     int          data;    // Integer data
     char         filename[15];

     strcpy(filename, DATAFILE);

     for(hashNum = 0; hashNum < 3; hashNum++){
         for(dHashNum = 0; dHashNum < 3; dHashNum++){
             InitTable(T, TABLESIZE);
             inFile = new ifstream();
             inFile->open(filename, ifstream::in);
             if(!inFile->is_open()){
                 cout << "Unable to open data file. Program terminating\n";
                 return 0;
             }

             count = 0;
             for(int i = 0; i < 50; i++){
                 inFile->getline(line, 64, '\n');
                 sscanf(line, "%s %d", key, &data);
                 count += HashInsert(T, key, data, hashNum, dHashNum);
             }

             cout << "Testing hash function " << hashNum + 1 << " using double hash " << dHashNum + 1 << ".\n";
             cout << "Total collisions = " << count << ".\n";
             for(int i=0; i < 100; i++){
                 if(strcmp(T[i].key, EMPTYKEY))
                     cout << "|";
                 else
                     cout << "-";
             }
             cout << "\n\n";
             inFile->close();
             delete inFile;
         }
     }
     return 1;
}

int HashInsert(HashStruct T[], char *key, int data, int hNum, int dhNum){
    int  testNum = (hNum * 3) + dhNum;
    int  colCount = 0;
    int  hashIndex, probeDec;

    switch(testNum){
    case 0 :  // Hash function 1 -- Double hash 1 (linear probing)
        hashIndex = Hash_1(key);
        probeDec = ProbeDec_1(key); // Function just returns 1 
        break;
    case 1 :  // Hash function 1 -- Double hash 2  
        hashIndex = Hash_1(key);
        probeDec = ProbeDec_2(key);
        break;
    case 2 :  // Hash function 1 -- Double hash 3
        hashIndex = Hash_1(key);
        probeDec = ProbeDec_3(key);
        break;
    case 3 :  // Hash function 2 -- Double hash 1 (linear probing)
        hashIndex = Hash_2(key);
        probeDec = ProbeDec_1(key); // Function just returns 1
        break;
    case 4 :  // Hash function 2 -- Double hash 2  
        hashIndex = Hash_2(key);
        probeDec = ProbeDec_2(key);
        break;
    case 5 :  // Hash function 2 -- Double hash 3
        hashIndex = Hash_2(key);
        probeDec = ProbeDec_3(key);
        break;
    case 6 :  // Hash function 3 -- Double hash 1 (linear probing)
        hashIndex = Hash_3(key);
        probeDec = ProbeDec_1(key); // Function just returns 1
        break;
    case 7 :  // Hash function 3 -- Double hash 2  
        hashIndex = Hash_3(key);
        probeDec = ProbeDec_2(key);
        break;
    case 8 :  // Hash function 3 -- Double hash 3  
        hashIndex = Hash_3(key);
        probeDec = ProbeDec_3(key);
        break;
    }

    while(strcmp(T[hashIndex].key, EMPTYKEY) != 0){
        colCount++;
        hashIndex -= probeDec;  // Decrementing was chosen you could also choose to
        if(hashIndex < 0)    //  increment and wrap back to the beginning of the table.
            hashIndex = hashIndex + TABLESIZE;
    }   

    strcpy(T[hashIndex].key, key);
    T[hashIndex].data = data;
    return colCount;
}

void InitTable(HashStruct hashT[], int TableSize){
    int i;

    for(i=0; i<TableSize; i++){
        strcpy(hashT[i].key, EMPTYKEY);
        hashT[i].data = 0;
    }
}

int Hash_1(char *key){
    int hash = 0;
    int prime = 29;
    int index = 0;

     for(int i = 0; i < 4; i++){
         hash = (key[i]-'0')*prime;
         for(int j = (3-i); j > 0; j--){
             hash *= prime;
         }
     }

     index = hash % TABLESIZE;
     return index;
}

int Hash_2(char *key){     // Folding
    int hash = 0;
    int index = 0;

    hash = (((key[0]-'0')+(key[1]-'0'))*37) + 
        (((key[1]-'0')+(key[2]-'0'))*47) + 
        (((key[2]-'0')+(key[3]-'0'))*67);

    index = hash % TABLESIZE;
    return index;
}

int Hash_3(char *key){     //Middle Squaring
    int hash = 0;
    int index = 0;

    hash = ((key[1]-'0') + (key[2]-'0'));
    hash *= hash;
    index = hash % TABLESIZE;
    return index;
}

int ProbeDec_1(char *key){
    return 1;
}

int ProbeDec_2(char *key){
    int dhash = 0;
    int index = 0;

    dhash = ((key[0]-'0')*97) + ((key[1]-'0')*83);
    index = dhash % TABLESIZE;
    return index;
}

int ProbeDec_3(char *key){
    int dhash = 0;
    int index = 0;

    dhash = (((key[0]-'0')*29) + ((key[1]-'0')*59) +
        ((key[2]-'0')*79) + ((key[3]-'0')*89));
    index = dhash % TABLESIZE;
    return index;
}

最佳答案

此代码中有很多错误检查,我只选择其中的一部分。

for(int i = 0; i < 50; i++){
  inFile->getline(line, 64, '\n');
  sscanf(line, "%s %d", key, &data);
  count += HashInsert(T, key, data, hashNum, dHashNum);
}

第 1+2 行:魔数(Magic Number)太多,如果混淆 50、64 和 4,则会出现错误。

第 3 行:sscanf 非常强大,但有些不安全,因为你不知道字符串的返回值有多长,一种方法是使字符串数组与读取的行一样长。

第 2+3 行返回值未检查。

char key[MAXLineLength];
const int LinesToRead = 100; // your hash array is 100, but you read only 50
const int NUMFIELDS = 2;
const int ERROR = -1; // there is a system return somewhere that is more correct.

for(int i = 0; i < LinesToRead ; i++){
  inFile->getline(line, MAXLineLength, '\n');
  if (!inFile->good())
    return ERROR;
  if (NUMFIELDS != sscanf(line, "%s %d", key, &data))
    return ERROR;
  if (strlen(key)!=4)
    return ERROR;
  count += HashInsert(T, key, data, hashNum, dHashNum);
}

关于C++ 程序结束而不是重复 For 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51609372/

相关文章:

python - 运行带有3GB RAM的python代码并使PC崩溃

Powershell ISE 在启动时崩溃

c++ - C 和 C++ 样式文件 IO 之间的性能差异

java - 增强的 for 循环

php - 翻译 PHP 工作日和月份

python - 无法在python中同步两个 "for loops"

visual-studio - 面对 Visual Studio 2015 和 2013 的突然崩溃

c++ - 如何在 Linderdaum Engine 场景中使用我的自定义着色器?

c++ - 使用 g++ 编译动态共享库

c++ - 检查 x264 Nal Units 的有效性