powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / В студии работает, а в консоли вылетает(Си)
8 сообщений из 8, страница 1 из 1
В студии работает, а в консоли вылетает(Си)
    #39359900
vlladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Программа на Си для подсчета сколько раз каждое слово встречается в тексте, с использованием хештаблицы. Написана в VS 2013 при запуске локальным отладчиком работает, а при запуске из консоли вылетает.
hash.c
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
#include "hashhead.h"

unsigned char hash(const char *str)
{
	unsigned int hash = 0;
	for (; *str; str++)
		hash = (hash * 1664525) + (unsigned char)(*str) + 1013904223;
	return hash>>24;
}
void insert(struct node *a[], char *word){
	unsigned char index;
	struct node *n, *p;
	p = findNode(word, a);
	if (p==NULL)
	{
		index = hash(word);
		n = (node*)malloc(sizeof(node*));
		strcpy_s(n->word,11, word);
		n->next = a[index];
		n->count = 1;
		a[index] = n;
	}
	else{
		p->count++;
	}
}

struct node *findNode(char *word, node* a[255]) {
	node *p;
	p = a[hash(word)];
	while (p && strcmp(p->word, word))
		p = p->next;
	return p;
}

void prntable(struct node *a[255]){
	int i;
	node *p;
	for (i = 0; i < 256; i++){
		p = a[i];
		while (p){
			printf("%s %d\n", p->word, p->count);
			p = p->next;
		}
	}
}

void prntable_f(struct node *a[255], FILE *f){
	int i;
	node *p;
	for (i = 0; i < 256; i++){
		p = a[i];
		while (p){
			fprintf(f,"%s %d\n", p->word, p->count);
			p = p->next;
		}
	}
}

int poscinstr(char *str, char c)
{
	unsigned int i;
	for (i = 0; i < strlen(str); i++){
		if (str[i] == c){
			return i;
		}
	}
	return -1;
}


hashhead.h
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
#ifndef HASHHEAD_H
#define HASHHEAD_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
void insert(struct node *a[], char *word);
unsigned char hash(const char *str);
void prntable(struct node *a[255]);
void prntable_f(struct node *a[255], FILE *f);
struct node *findNode(char *word, struct node *a[]);
typedef struct node
{
	char word[11];
	int count;
	struct node *next;
}node;

int poscinstr(char *str, char c);
#endif /*HASHHEAD_H*/


hashtest.c
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
#include "hashhead.h"

void main(int argc, char *argv[]) {

	node *a[256];
	FILE *f = stdout;
	FILE *fi = stdin;
	char str[2000];
	char word_t[50];
	char *estr, *letters, *symbols;
	unsigned int j;
	int k;
	letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	for (j = 0; j < 256; j++){
		a[j] = (node*)malloc(sizeof(node*));
		a[j] = NULL;
	}
	switch (argc) {
	case 1:
		printf("hashtable, version 0.0.0.1 x86\n");
		printf("Usage: Input an text file\n");
		printf("hashtable.exe -in filename -o|-out filename\n");
		printf("Output: file containing amount of each word\n");
		break;
	case 2:
		if ((strcmp(argv[1], "-help") == 0) || (strcmp(argv[1], "-HELP") == 0)){
			printf("hashtable, version 0.0.0.1 x86\n");
			printf("Usage: Input an text file\n");
			printf("hashtable.exe -in filename -o|-out filename\n");
			printf("Output: file containing amount of each word\n");
			break;
		}
	case 3:
		if (strcmp(argv[1], "-in") == 0){
			if (fopen_s(&fi, argv[2], "r") == 0)
			{
				while (1){
					estr = fgets(str, 2000, fi);
					if (estr == NULL)
					{
						if (feof(fi) != 0)
						{
							fclose(fi);
							break;
						}
						else
						{
							printf("\nFile read error\n");
							break;
						}
					}
					j = 0;
					while ((poscinstr(letters, str[j]) <0) && (j < strlen(str))){
						j++;
					}
					k = 0;
					while (j < strlen(str)){
						word_t[k] = str[j];
						k++;
						j++;
						if (poscinstr(letters, str[j]) <0){
							word_t[k] = '\0';
							if ((strlen(word_t) < 11) && (strlen(word_t) > 0)) {
								insert(a, word_t);
							}
							k = 0;
							while ((poscinstr(letters, str[j]) <0) && (j < strlen(str))){
								j++;
							}
						}
					}
					word_t[k] = '\0';
					if ((strlen(word_t) < 11) && (strlen(word_t) > 0)) {
						insert(a, word_t);
					}
				}
				prntable(a);
				getchar();
				break;
			}
			else{
				printf("Input file not opened.");
				getchar();
				break;
			}
		}
	case 5:
		if ((strcmp(argv[1], "-in") == 0) && ((strcmp(argv[3], "-o") == 0) || (strcmp(argv[3], "-out") == 0))){
			if (fopen_s(&fi, argv[2], "r") == 0)
			{
				while (1){
					estr = fgets(str, 2000, fi);
					if (estr == NULL)
					{
						if (feof(fi) != 0)
						{
							fclose(fi);
							break;
						}
						else
						{
							printf("\nFile read error\n");
							break;
						}
					}
					j = 0;
					while ((poscinstr(letters, str[j]) < 0) && (j < strlen(str))){
						j++;
					}
					k = 0;
					while (j < strlen(str)){
						word_t[k] = str[j];
						k++;
						j++;
						if (poscinstr(letters, str[j]) <0){
							word_t[k] = '\0';
							if ((strlen(word_t) < 11) && (strlen(word_t) > 0)) {
								insert(a, word_t);
							}
							k = 0;
							while ((poscinstr(letters, str[j]) < 0) && (j < strlen(str))){
								j++;
							}
						}
					}
					word_t[k] = '\0';
					if ((strlen(word_t) < 11) && (strlen(word_t) > 0)) {
						insert(a, word_t);
					}
				}
				if (fopen_s(&f, argv[4], "w") == 0)
				{
					prntable_f(a, f);
					fclose(f);
				}
				else{
					printf("Output file not opened.");
					getchar();
					break;
				}
				break;
			}
			else{
				printf("Input file not opened.");
				getchar();
				break;
			}
		}
	}
	return;
}

...
Рейтинг: 0 / 0
В студии работает, а в консоли вылетает(Си)
    #39359906
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vlladimirа при запуске из консоли вылетает
А она, случайно так, при этом не пишет "многа нипанятных букафф", включающих в себя точную
причину и место ошибки, а так же call stack, приведших к этому?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
В студии работает, а в консоли вылетает(Си)
    #39359913
vlladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov, Нет просто вылетает и все (Прекращена работа программы)
...
Рейтинг: 0 / 0
В студии работает, а в консоли вылетает(Си)
    #39359923
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vlladimirНет просто вылетает и всене удивительно
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
void prntable(struct node *a[255]){
	int i;
	node *p;
	for (i = 0; i < 256; i++){
		p = a[i];
		while (p){
			printf("%s %d\n", p->word, p->count);
			p = p->next;
		}
	}
}

выход за пределы массива всегда заканчиваются не приятно
...
Рейтинг: 0 / 0
В студии работает, а в консоли вылетает(Си)
    #39359928
alexy_black
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"что только не делают люди чтобы не использовать ..." wc
или вот так "юзай wc а то будет wc" :)
...
Рейтинг: 0 / 0
В студии работает, а в консоли вылетает(Си)
    #39359944
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vlladimir
Код: plaintext
1.
2.
3.
	struct node *n, ...;
	...
		n = (node*)malloc(sizeof(node*));

Вы запрашиваете блок памяти размером с указатель, а надо запрашивать блок памяти размером с node:
Код: plaintext
1.
n = (node*)malloc(sizeof(node));


vlladimir
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int poscinstr(char *str, char c)
{
	unsigned int i;
	for (i = 0; i < strlen(str); i++){
		if (str == c){
			return i;
		}
	}
	return -1;
}

Так лучше не писать, потому что функция strlen вызывается на [i]каждой
итерации цикла. Вообще, для поиска char-а в ноль-завершаемой строке есть стандартная функция strchr :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
#include <string.h>

int find_char(const char s[], char c) {
  const char* p;
  p = strchr(s, c);
  return (p != NULL ? (int)(p - s) : -1);
}


vlladimir
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
	node *a[256];
	...
	unsigned int j;
	...
	for (j = 0; j < 256; j++){
		a[j] = (node*)malloc(sizeof(node*));
		a[j] = NULL;
	}

Отмеченная строка не нужна.

vlladimir
Код: plaintext
1.
estr = fgets(str, 2000, fi);

Все современные компьютеры оснащены гигабайтами оперативной памяти, поэтому при работе с текстовыми файлами в большинстве случаев нет смысла заморачиваться на чтение файла по кусочкам. Проще загрузить весь файл в один буфер, и работать с ним как с большой строкой, например так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

char* load_text_file(const char path[]) {
  FILE* file;
  size_t size;
  char* text;

  /* 'b' чтобы не тратить время на замену "\r\n" (CR LF) -> "\n" (LF) */
  file = fopen(path, "rb");

  /* узнаём размер файла */
  fseek(file, /*offset:*/0, SEEK_END);
  size = ftell(file);
  fseek(file, /*offset:*/0, SEEK_SET);

  text = (char*)malloc(size + 1);
  fread(text, 1, size, file);
  text[size] = '\0';

  fclose(file);

  return text;
}

bool is_letter(char c);
void handle_word(const char word[], size_t word_len);

void load_words(const char file_path[]) {
  char* text;
  size_t pos, word_pos;

  text = load_text_file(file_path);

  pos = 0;
  for (;;) {
    /* пропускаем не-буквы */
    for (;;) {
      if (is_letter(text[pos]) || (text[pos] == '\0'))
        break;
      pos++;
    }

    if (text[pos] == '\0')
      break;

    /* сканируем слово */
    word_pos = pos;
    pos++; /* пропускаем первую букву */
    while (is_letter(text[pos]))
      pos++;

    handle_word(text + word_pos, /*word_len:*/ pos - word_pos);
  }

  free(text);
}

bool is_letter(char c) {
  return (('a' <= c) && (c <= 'z')) || (('A' <= c) && (c <= 'Z'));
}

void handle_word(const char word[], size_t word_len) {
  /* строка word не завершается нулевым char-ом ('\0'), поэтому явно указываем длину */
  printf("%.*s\n", (int)word_len, word);
}

Обработку ошибок не писал, чтобы код был проще. Но по-хорошему, ошибки надо обрабатывать. Есть два способа: коды возврата и исключения ( setjmp / longjmp , или тупо exit ). Какой способ лучше -- holy war.

egorychvlladimirНет просто вылетает и всене удивительно
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
void prntable(struct node *a[255]){
	int i;
	node *p;
	for (i = 0; i < 256; i++){
		p = a[i];
		while (p){
			printf("%s %d\n", p->word, p->count);
			p = p->next;
		}
	}
}

выход за пределы массива всегда заканчиваются не приятноА там как раз массив длины 256:
vlladimir
Код: plaintext
1.
2.
3.
void main(int argc, char *argv[]) {

	node *a[256];

поэтому с индексом всё нормально. А то, что в заголовках функций написано «struct node *a[255]», значения не имеет, потому что длина массива реально не передаётся. Но лучше конечно поправить, а то сбивает с толку.
...
Рейтинг: 0 / 0
В студии работает, а в консоли вылетает(Си)
    #39359980
vlladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пётр Седов, Спасибо огромное!
n = (node*)malloc(sizeof(node));
Дело было в этой строке, после правки все заработало, ну и кое-что еще поправил по вашим советам, еще раз спасибо!!!
...
Рейтинг: 0 / 0
В студии работает, а в консоли вылетает(Си)
    #39360330
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vlladimirПётр Седов, Спасибо огромное!
n = (node*)malloc(sizeof(node));
Дело было в этой строке, после правки все заработало, ну и кое-что еще поправил по вашим советам, еще раз спасибо!!!


не, дело не только в этой строке...
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / В студии работает, а в консоли вылетает(Си)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]