@HNKHENM

Где мог не доглядеть?

Нужно было написать программу считывающую из файла слова , а потом из этих слов вычислить с помощью хеш-функции адрес и вывести результаты хеширования.Первоначально нужно было написать программу на паскале , собственно на нём она и работает исправно , но попытавшись написать ее с помощью с++ выскакивают ошибки на этапе компиляции , вот одна из них:

Первый этап обработки исключения по адресу 0x6E1808A5 (msvcr120d.dll) в Проект7.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xCCCCCCCC.
Необработанное исключение по адресу 0x6E1808A5 (msvcr120d.dll) в Проект7.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xCCCCCCCC.


В чем может быть загвостка?
#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdlib.h>
using namespace std;
const int n = 15;
int hashStr(char str[n]){

	unsigned int i;
	int key = 0;

	for (i = 1; i < strlen(str); i++){

		key += (int)str[i];

	}
	return (key % n) + 1;
}
int main()
{
	setlocale (LC_ALL, "RUS");
	bool b;
	unsigned int count, i;
	string rec[n];
	fstream F;
	char s[n];
	int j;
	count = 0;



	F.open("test.txt");

	for (j = 1; j < n; j++){

		rec[j] = "";

	}

	if (F){

		while (!F.eof()){

			b = false;
			F >> s;
			j = hashStr(s);

			if (rec[j] == "" || s == rec[j]) {
			
				rec[j] = s;
				b = true;
			
			}
			else{
			
				for (count = 1; count <= n; count++){
				
					if (rec[(j + count) % n + 1] == "" || s == rec[(j + count) % n + 1]){
					
						j = (j + count) % n + 1;
						rec[j] = s;
						b = true;
						break;
					
					}
				
				}
			
			}
			if (b == true){
			
				cout << s << " Найдено в позиции " << j << " количество сравнений " << count <<endl ;

			}
			else{
			
				cout << s << " не найдено , количество сравнений "<< count << endl;
				count = 0;
			
			}

		}
		F.close();
	}

	else cout << " Файл не существует" << endl;

	system("pause");

	return 0;

}


Если нужно содержимое текстового файла то вот:

Audi
Saab
Bentley
Infinity
Hummer
Hummer
Fiat
Jeep
Cadillac
VolksWagen
Daewoo
Mersedes
Dodge
Mitsubishi
Lamborgini
  • Вопрос задан
  • 4030 просмотров
Решения вопроса 1
gbg
@gbg Куратор тега Программирование
Любые ответы на любые вопросы
  1. Счет массивов в С начинается с 0
  2. Инициализация строк сразу после создания бессмысленна, они и так пустые
  3. К главной ошибке вас привел поганый паскальский стиль объявлять одну индексную переменную на все циклы - счетчик должен быть объявлен прямо в операторе for(int j=0....; у вас же j после цикла равна n и таким образом находится за границей массива, отсюда - падение программы.
  4. Еще одно место для падения F >> s; - если строка длиннее 14(!)* символов - будет переполнение
  5. С каких пор поэлементное суммирование стало называться хэшированием? Коллизий будет огромное количество. C++11 например имеет встроенные средства для хэширования. В любом случае, на вход хэширующей функции лучше передавать константную ссылку на std::string а не массив символов


HNKHENM: если вы заинтересованы в улучшении этого кода:
  • замените массивы на контейнеры (массив символов - на строку, массив строк - на вектор из них);
  • включите С++11, если компилятор не поддерживает, отправьте его на пенсию.
  • перебор символов в строке реализуйте циклом for из стандарта C++11
  • повсеместно используйте auto
  • откажитесь от дурной привычки для итерации сущностей с неотрицательным индексом использовать int, используйте size_t

______________________________________________________
*Не забывайте, что самый последний символ в строке - маркер ее окончания \0
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы