Премини към съдържанието
Форумът в приложение

По-лесно сърфиране. Научи повече.

Kaldata.com - Форуми

Приложение на форума на цял екран с push известия, значки и други.

За да инсталирате това приложение на iOS и iPadOS
  1. Докоснете Иконата за споделяне в Safari
  2. Превъртете менюто и докоснете Добавяне към началния екран.
  3. Докоснете Добавяне в горния десен ъгъл.
За да инсталирате това приложение на Android
  1. Докоснете менюто с 3 точки (⋮) в горния десен ъгъл на браузъра.
  2. Докоснете Добавяне към началния екран или Инсталиране на приложение.
  3. Потвърдете, като докоснете Инсталиране.

Добре дошли!

Добре дошли в нашите форуми, пълни с полезна информация. Имате проблем с компютъра или телефона си? Публикувайте нова тема и ще намерите решение на всичките си проблеми. Общувайте свободно и открийте безброй нови приятели.

Моля, регистрирайте се за да публикувате тема и да получите пълен достъп до всички функции.

 

Речник на C

Featured Replies

Здравейте!Обръщам се към вас защото имам проблем с курсова работа.Значи заданието ми е следното:

Да се напише речник който записва думите от въведени изречение и честотата с която те се срещат.

Ето кода който аз успях да напиша и зациклих:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#define MAX_LENGHT 30
#define DIM 100

struct rechnik{
    char izrechenie[DIM+1];
	char duma[MAX_LENGHT+1];
	int chestota;
};
void enter(rechnik **ptr);
void print(rechnik **ptr);
void buble(rechnik *x[], int n);

int main()
{
    int n,i;
	rechnik *list[DIM] , *ptr=NULL;
	do
	{
		printf("Vyvedi izrechenie:");
проблема ми е функцията за въвеждане на изречение и разделянето на изречението на думи. Благодаря предварително!

Колега имам няколко въпроса: 1.До кога трябва да се въвеждат изречения или думи? 2.Защо си ги сложил в масив от това разбирам че са с точно определена дължина така ли? 3.Може ли точното условие на задачата? 4.Какво означава честотата с която те се срещат?-Тоест да сложа брояч и да броя коя дума колко пъти се среща в дадено изречение така ли?

Редактирано от Kras4ooo (преглед на промените)

  • Автор

Колега имам няколко въпроса:

1.До кога трябва да се въвеждат изречения или думи?

2.Защо си ги сложил в масив от това разбирам че са с точно определена дължина така ли?

3.Може ли точното условие на задачата?

4.Какво означава честотата с която те се срещат?-Тоест да сложа брояч и да броя коя дума колко пъти се среща в дадено изречение така ли?

1:може да си въвеждаш изречения докато на се зададе EOF

2:в масив съм ги сложил за да ми е по лесно после при печата защото още не сме взели целия материал за списъците.

3:

Задача: Да се напише програма,която:
1.Създава речник от думите на зададен входен стринг.
2.Съставеният речник да се разпечатва на екрана.
3.Програмата да има текстово меню, в което потребителят да избира дали да въвежда стринг или да обработва вече въведен такъв.
4.Да се добави възможност за прочитане на текст от файл.
5.Да се добави възможност речника да може да сортира по азбучен ред.
6.Да се добави визможност речника да се записва във файл,въведен от потребителя.
4.Честотата означава точно това което си написал.

Редактирано от Nikolai Lekov (преглед на промените)

  • Автор

до тук стигнах и явно бъркам някаде защото ми дава грешка....

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define MAX_LENGHT 30
#define DIM 100

struct Rechnik{
    char izrechenie[DIM+1];
	char duma[MAX_LENGHT+1];
	int chestota;
};
void enter(Rechnik **ptr);
void print(Rechnik **ptr);
void buble(Rechnik *x[], int n);

int main()
{
    int i;
	Rechnik *list[DIM] , *ptr=NULL;
	printf("Vyvedi izrechenie\n");
	for(i=0; i<DIM; i++)
	{
		enter(&ptr);
		if(ptr !=NULL) list[i]=ptr;
	}
	printf("\nRechnik:\n\n");
	printf("Duma\tChestota\n");
	for(i=0; i<DIM; i++)
		print(list[i]);

		free(list[i]);
	return 0;
}
void enter(Rechnik **ps)
{
    int i;
    Rechnik *temp;
	*ps = (Rechnik *)malloc( sizeof(Rechnik));
	if(*ps == NULL) return;
	fflush(stdin);
	printf("\nIzrechenie:");
	gets((*ps)->izrechenie);
	*temp=(*ps->izrechenie);
	while(*temp != '\0')
	{
	for (i=0; i++)
	if(*temp !=' ' || *temp !=',' || *temp !='.' || *temp !='!' || *temp !='?' || *temp !='\t')
	gets((*ps)->duma);
	}
}
void print(Rechnik *ps)
{
	printf("%s\t%d\n",ps->duma,ps->chestota);
}

Виждам, че dvader те гърчи в другия форум! ;) Имам подобна задача на твоята, чете от файл или от клавиатурата, прави и сортира речник, като за разделители между думите използва символите, дефинирани в isspace()! Но можеш да си промениш какви разделители да ползва (чрез функция is_word_delim() ако е необходимо)! Отчита препинателните знаци като части от думите, но това и сам можеш да си го оправиш! ;)

dictionary.c

#include <stdio.h>  // printf(), fgetc(), perror(), fopen(), fclose(), feof()
#include <stdlib.h> // realloc(), malloc(), free(), qsort()
#include <ctype.h>  // isspace()
#include <string.h> // strlen(), strcpy(), strcmp()
#include "dictionary_operations.h"

char * read_word(FILE * f, char * word)
{
	if (!f || feof(f) || !word) return NULL;
	int ch = fgetc(f);
	char * orig = word;
	while ( !isspace( ch ) && ch != EOF ) {	// custom is_word_delim() can be used!
		//printf("ch = %c (%d)\n", ch, ch);
		*word++ = ch;
		ch = fgetc(f);
	}
	*word = '\0';
	return orig;
}

#define WBF_SIZE 128    // word buffer size

int main(int argc, char *argv[])
{
	word * dict = NULL;
	char word_buffer[WBF_SIZE] = { 0 };
	unsigned long int size = 0;
	
	FILE * f = NULL;
	if (argc == 2) f = fopen(argv[1],"r");
	else f = stdin;
	if (!f) {
		perror("Error opening text file");
		printf("Using standart input instead\n\n");
		f = stdin;
	}
	
	while (!feof(f)) {
		read_word(f,word_buffer);
		//printf("%s[%d]\n",word_buffer,strlen(word_buffer));
		if (strlen(word_buffer)) dict = add_to_dict(dict, &size, word_buffer);
	}

	if (f != stdin) fclose(f);
	
	qsort(dict, size, sizeof(struct _word), word_cmp);
	print_dict(dict,size);
	free_dict(dict,size);
	return 0;
}

dictionary_operations.h

typedef struct _word {
	char * w;
	unsigned long int freq;
} word;

/* --- Misc Helper functions --- */
inline unsigned short int num_digits(long int n)
{
	unsigned short int digits = 0;
	while (n) {
		n /= 10;
		digits++;
	}
	return digits;
}

int word_cmp (const void * s1, const void * s2)	// for qsort()
{
	return strcmp( ((word *) s1)->w, ((word *) s2)->w );
}

/* --- END Of Misc Helper functions --- */

/* --- Dictionary functions --- */

long int search_dict(word const * d, unsigned long int const size, char const * word)
{
	if (!d || !size) return -1;
	unsigned long int i = 0;
	for (i = 0; i < size; ++i) {
		//printf("Comparing: %s :: %s\n",d[i].w,word);
		if (!strcmp(d[i].w, word)) return i;
	}
	return -1;
}

word * add_to_dict(word * d, unsigned long int * dict_size, char const * new_word)
{
	if ( !dict_size || !new_word || !(*new_word) ) return d;
	
	//printf("Dict size: Old(%d) New(%d)\n",*dict_size,(*dict_size)+1);
	//printf("Adding word: %s (len %d)\n",new_word,strlen(new_word));
	long int search_index = search_dict(d, *dict_size, new_word);
	if (search_index > -1) {
		d[search_index].freq++;
	}
	else {
		d = (struct _word *) realloc(d, sizeof(struct _word) * ++(*dict_size) );
		d[(*dict_size)-1].w = (char *) malloc( sizeof(char) * (strlen(new_word)+1) );
		strcpy(d[(*dict_size)-1].w, new_word);
		d[(*dict_size)-1].freq = 1;
	}
	return d;
}

void print_dict(word const * d, unsigned long int const size)
{
	if (!d || !size) return;
	unsigned long int i = 0, total_word_repetitions = 0;
	unsigned short int size_digits = num_digits(size);
	unsigned short int max_word_len = 0, max_freq_digits = 0;

	for (i = 0; i < size; ++i) {	// First pass, gather statistics for a good tabulation.
		total_word_repetitions += d[i].freq;
		if (strlen(d[i].w) > max_word_len) max_word_len = strlen(d[i].w);
		if (d[i].freq > max_freq_digits) max_freq_digits = d[i].freq;
	}
	max_freq_digits = num_digits(max_freq_digits);
	
	for (i = 0; i < size; ++i)  // Second pass, print out.
	    printf(" %*lu: %*s (%2u) [%*lu]\n",size_digits,i+1, max_word_len,d[i].w,strlen(d[i].w), max_freq_digits,d[i].freq);

	printf("\n Unique words: %lu\tTotal words: %lu\n", size, total_word_repetitions);
}

void free_dict(word * d, unsigned long int const size)
{
	if (!d || !size) return;
	unsigned long int i = 0;
	for (i = 0; i < size; ++i)
	    free(d[i].w);
	free(d);
}

А това, което "си написал", ми се вижда доста сбъркано! Работиш със статични масиви, нямаш защити срещу препълвана на масивите! Като прочетеш ps->izrechenie в enter(), надолу цялата функция не прави нищо смислено! За токенизиране си има готова функция - strtok(), в случай, че не се справиш с инструкциите на колегите от другия форум! А как искаш да запазиш едно изречение и всички думи в него или само първата? Изобщо не виждам защо четеш по едно изречение точно и тогава искаш да токенизираш?!?

P.S. Не разчитай толкова на форумите, колкото на това, да ходиш на лекции, да си учиш редовно и да се помъчиш да си го направиш сам! Никой не обича да помага на хора, които не са си мръднали пръста да си свършат личната работа, а разчитат на други хора да им я свършат и при това съвсем безвъзмездно!

  • Автор

Виждам, че dvader те гърчи в другия форум! :cool: Имам подобна задача на твоята, чете от файл или от клавиатурата, прави и сортира речник, като за разделители между думите използва символите, дефинирани в isspace()! Но можеш да си промениш какви разделители да ползва (чрез функция is_word_delim() ако е необходимо)! Отчита препинателните знаци като части от думите, но това и сам можеш да си го оправиш! ;)

dictionary.c

#include <stdio.h>  // printf(), fgetc(), perror(), fopen(), fclose(), feof()
#include <stdlib.h> // realloc(), malloc(), free(), qsort()
#include <ctype.h>  // isspace()
#include <string.h> // strlen(), strcpy(), strcmp()
#include "dictionary_operations.h"

char * read_word(FILE * f, char * word)
{
	if (!f || feof(f) || !word) return NULL;
	int ch = fgetc(f);
	char * orig = word;
	while ( !isspace( ch ) && ch != EOF ) {	// custom is_word_delim() can be used!
		//printf("ch = %c (%d)\n", ch, ch);
		*word++ = ch;
		ch = fgetc(f);
	}
	*word = '\0';
	return orig;
}

#define WBF_SIZE 128    // word buffer size

int main(int argc, char *argv[])
{
	word * dict = NULL;
	char word_buffer[WBF_SIZE] = { 0 };
	unsigned long int size = 0;
	
	FILE * f = NULL;
	if (argc == 2) f = fopen(argv[1],"r");
	else f = stdin;
	if (!f) {
		perror("Error opening text file");
		printf("Using standart input instead\n\n");
		f = stdin;
	}
	
	while (!feof(f)) {
		read_word(f,word_buffer);
		//printf("%s[%d]\n",word_buffer,strlen(word_buffer));
		if (strlen(word_buffer)) dict = add_to_dict(dict, &size, word_buffer);
	}

	if (f != stdin) fclose(f);
	
	qsort(dict, size, sizeof(struct _word), word_cmp);
	print_dict(dict,size);
	free_dict(dict,size);
	return 0;
}

dictionary_operations.h

typedef struct _word {
	char * w;
	unsigned long int freq;
} word;

/* --- Misc Helper functions --- */
inline unsigned short int num_digits(long int n)
{
	unsigned short int digits = 0;
	while (n) {
		n /= 10;
		digits++;
	}
	return digits;
}

int word_cmp (const void * s1, const void * s2)	// for qsort()
{
	return strcmp( ((word *) s1)->w, ((word *) s2)->w );
}

/* --- END Of Misc Helper functions --- */

/* --- Dictionary functions --- */

long int search_dict(word const * d, unsigned long int const size, char const * word)
{
	if (!d || !size) return -1;
	unsigned long int i = 0;
	for (i = 0; i < size; ++i) {
		//printf("Comparing: %s :: %s\n",d[i].w,word);
		if (!strcmp(d[i].w, word)) return i;
	}
	return -1;
}

word * add_to_dict(word * d, unsigned long int * dict_size, char const * new_word)
{
	if ( !dict_size || !new_word || !(*new_word) ) return d;
	
	//printf("Dict size: Old(%d) New(%d)\n",*dict_size,(*dict_size)+1);
	//printf("Adding word: %s (len %d)\n",new_word,strlen(new_word));
	long int search_index = search_dict(d, *dict_size, new_word);
	if (search_index > -1) {
		d[search_index].freq++;
	}
	else {
		d = (struct _word *) realloc(d, sizeof(struct _word) * ++(*dict_size) );
		d[(*dict_size)-1].w = (char *) malloc( sizeof(char) * (strlen(new_word)+1) );
		strcpy(d[(*dict_size)-1].w, new_word);
		d[(*dict_size)-1].freq = 1;
	}
	return d;
}

void print_dict(word const * d, unsigned long int const size)
{
	if (!d || !size) return;
	unsigned long int i = 0, total_word_repetitions = 0;
	unsigned short int size_digits = num_digits(size);
	unsigned short int max_word_len = 0, max_freq_digits = 0;

	for (i = 0; i < size; ++i) {	// First pass, gather statistics for a good tabulation.
		total_word_repetitions += d[i].freq;
		if (strlen(d[i].w) > max_word_len) max_word_len = strlen(d[i].w);
		if (d[i].freq > max_freq_digits) max_freq_digits = d[i].freq;
	}
	max_freq_digits = num_digits(max_freq_digits);
	
	for (i = 0; i < size; ++i)  // Second pass, print out.
	    printf(" %*lu: %*s (%2u) [%*lu]\n",size_digits,i+1, max_word_len,d[i].w,strlen(d[i].w), max_freq_digits,d[i].freq);

	printf("\n Unique words: %lu\tTotal words: %lu\n", size, total_word_repetitions);
}

void free_dict(word * d, unsigned long int const size)
{
	if (!d || !size) return;
	unsigned long int i = 0;
	for (i = 0; i < size; ++i)
	    free(d[i].w);
	free(d);
}

А това, което "си написал", ми се вижда доста сбъркано! Работиш със статични масиви, нямаш защити срещу препълвана на масивите! Като прочетеш ps->izrechenie в enter(), надолу цялата функция не прави нищо смислено! За токенизиране си има готова функция - strtok(), в случай, че не се справиш с инструкциите на колегите от другия форум! А как искаш да запазиш едно изречение и всички думи в него или само първата? Изобщо не виждам защо четеш по едно изречение точно и тогава искаш да токенизираш?!?

P.S. Не разчитай толкова на форумите, колкото на това, да ходиш на лекции, да си учиш редовно и да се помъчиш да си го направиш сам! Никой не обича да помага на хора, които не са си мръднали пръста да си свършат личната работа, а разчитат на други хора да им я свършат и при това съвсем безвъзмездно!

мерси за помоща и да ти кажа нито една лекция или упражнение не съм изпуснал просто в ТУ-София ни мъчат доста повече отколкото преподават и накрая става гаф...
  • 3 седмици по-късно...
  • Автор

Колеги ще може ли малко помощ относно добавяне на едно меню към тази програма в което да има опцията за прочитане на текст от файл и опция за обработка на вече въведения стринг,защото аз зациклих как ли не го мъчих нестава пък и кошника ми нещо ми дава бъгове. Изберете опция от следното меню: 1: Сортиране на речника по азбучен ред. 2: Прочитане на текст от файл. Благодаря ви много предварително.

Колега, програмата, която съм ти написал горе работи по следния начин:

Отваряш DOS прозорец и стартираш програмата

D:\Documents\C++\dictionary>dictionary
this
is a
test
sentance to demonstrate the way
this program
works
^Z
  1:           a ( 1) [1]
  2: demonstrate (11) [1]
  3:          is ( 2) [1]
  4:     program ( 7) [1]
  5:    sentance ( 8) [1]
  6:        test ( 4) [1]
  7:         the ( 3) [1]
  8:        this ( 4) [2]
  9:          to ( 2) [1]
 10:         way ( 3) [1]
 11:       works ( 5) [1]

 Unique words: 11       Total words: 12
Както виждаш, когато я стартирам без параметри, въвеждаш думи, докато не въведеш Ctrl+Z (^Z) (End of File)! След това принтира сортирания речник като в първите скоби е дължината на думата, а във вторите - колко пъти се среща!

Сега стартирам програмата с параметър името на текстов файл:

D:\Documents\C++\dictionary>dictionary text.txt
  1:          In ( 2) [1]
  2:   On-demand ( 9) [1]
  3:         and ( 3) [1]
  4:         are ( 3) [2]
  5: consumption (11) [1]
  6:     control ( 7) [1]
  7:   efficient ( 9) [1]
  8: established (11) [1]
  9:    general, ( 8) [1]
 10:    minimize ( 8) [1]
 11:        more ( 4) [1]
 12:   on-demand ( 9) [1]
 13:       ones. ( 5) [1]
 14:        only ( 4) [1]
 15:    overhead ( 8) [1]
 16:       power ( 5) [1]
 17:   proactive ( 9) [1]
 18:   protocols ( 9) [2]
 19:    reactive ( 8) [1]
 20:   required. ( 9) [1]
 21:      routes ( 6) [1]
 22:       since ( 5) [1]
 23:        than ( 4) [1]
 24:        when ( 4) [1]

 Unique words: 24       Total words: 26
Поведението е предвидимо, отваря файла, чете думите, прави речник и го принтира сортиран!

Ако се опиташ да стартираш програмата с параметър файл, който не съществива, автоматично те връща в първия случай:

D:\Documents\C++\dictionary>dictionary nonexistent.txt
Error opening text file: No such file or directory
Using standart input instead

_

Както виждаш, програмата работи, както с изречения в текстов файл, така и с изречения, въведени от клавиатурата! Не съм я правил с меню, защото, според мен, така е по-елегантно! За да го преправиш с меню се изискват елементарни корекции! Ако не можеш да се справиш значи не си седнал да прочетеш един ред! Покажи какво си написаш сам до сега и ще го обсъдим! :ph34r:

Успех!

  • Автор
#include <stdio.h>  // printf(), fgetc(), perror(), fopen(), fclose(), feof()
#include <stdlib.h> // realloc(), malloc(), free(), qsort()
#include <ctype.h>  // isspace()
#include <string.h> // strlen(), strcpy(), strcmp()
#include "dictionary_operations.h"

char * read_word(FILE * f, char * word)
{
        if (!f || feof(f) || !word) return NULL;
        int ch = fgetc(f);
        char * orig = word;
        while ( !isspace( ch ) && ch != EOF ) { // custom is_word_delim() can be used!
                //printf("ch = %c (%d)\n", ch, ch);
                *word++ = ch;
                ch = fgetc(f);
        }
        *word = '\0';
        return orig;
}

#define WBF_SIZE 128    // word buffer size

int main()
{
		int argc;
		char argv[20];
        word * dict = NULL;
        char word_buffer[WBF_SIZE] = { 0 };
        unsigned long int size = 0;
        
        FILE * f = NULL;
		printf("Vyvedi string, ili izberi opciq ot slednoto \n\n\tMENU:\n\t1: Sortirane po azbuchen red\n\t2:Prochitane na tekst ot fail\n\t3:Izhod\n");
		scanf("%d",&argc);
			switch(argc){
		case '1': 
		    qsort(dict, size, sizeof(struct _word), word_cmp);
			print_dict(dict,size);
			break;
		case '2':
			printf("Vyvedi ime na fail\n");
			gets(argv);
			f = fopen(argv,"r");
			break;
		case '3':
			free_dict(dict,size);
			break;
		default: 
			f = stdin;
			break;
		}
        if (!f) {
                perror("Error opening text file");
                printf("Using standart input instead\n\n");
                f = stdin;
        }
        
        while (!feof(f)) {
                read_word(f,word_buffer);
                //printf("%s[%d]\n",word_buffer,strlen(word_buffer));
                if (strlen(word_buffer)) dict = add_to_dict(dict, &size, word_buffer);
        }

        if (f != stdin) fclose(f);
        
        qsort(dict, size, sizeof(struct _word), word_cmp);
        print_dict(dict,size);
        free_dict(dict,size);
        return 0;
}
колега това е което аз успях да напиша но когато въведа число от изброените и нищо не се получава...
argv[] и argc не работят така ако не са параметри на main()! Много си го омазал, ако ми остане време довечера, ще ти я напиша!

Използвай тази нова main() функция с меню! Разбира се, може да бъде реализирано и със switch()!

#define EVER (; /* to mess with the teachers */
int main()
{
	word * dict = NULL;
	char word_buffer[WBF_SIZE] = { 0 }, fname[FILENAME_MAX] = { 0 };
	unsigned long int size = 0, choice = 0;
	FILE * f = NULL;
	
	for EVER {
		do {
			printf(" 1. Input from keyboard\n");
			printf(" 2. Input from file\n");
			printf(" 3. Sort dictionary\n");
			printf(" 4. Exit\n");
			fflush(stdin);
			choice = getchar();
		} while (choice != '1' && choice != '2' && choice != '3' && choice != '4');
		if (choice == '1') {
			if (dict) { free_dict(dict,size); size = 0; }
			f = stdin;
		}
		if (choice == '2') {
			if (dict) { free_dict(dict,size); size = 0; }
			printf("  Filename: ");
			fflush(stdin);
			fgets(fname,FILENAME_MAX-1,stdin);
			fname[strlen(fname)-1] = '\0'; /* get rid of the appended '\n' */
			if ( (f = fopen(fname,"r")) == NULL) {
				perror("Error opening text file");
				printf("Using standart input instead\n\n");
				f = stdin;
				fflush(stdin);
			}
		}
		if (choice == '3') {
			if (!dict || !size) printf(" No input!\n\n");
			else {
				qsort(dict, size, sizeof(struct _word), word_cmp);
				print_dict(dict,size);
			}
			continue;
		}
		if (choice == '4') {
			if (dict) free_dict(dict,size);
			return 0;
		}
		
		while (!feof(f)) {
			read_word(f,word_buffer);
			//printf("%s[%d]\n",word_buffer,strlen(word_buffer));
			dict = add_to_dict(dict, &size, word_buffer);
		}
		if (f != stdin) fclose(f);
		print_dict(dict,size);
	}

	return 0;
}
Ако видиш бъгове свиркай, че не съм внимавал много!

Ако искаш още нови функционалности и опции в менюто, време да се помъчиш сам! Аз помагам само с идеи! :help:

Регистрирайте се или влезете в профила си за да коментирате

Разглеждащи това в момента 0

  • Няма регистрирани потребители разглеждащи тази страница.

Дарение

  • Подкрепи съществуването на форума - направи дарение
    32%
    Дарени 315 € от нужните 1 000 €

Бюлетин

Получавайте известие, когато има важна промяна или новина свързана с форума.

Профил

Навигация

Търсене

Търсене

Конфигуриране на push известия в браузъра

Chrome (Android)
  1. Докоснете иконата на катинар до адресната лента.
  2. Докоснете Разрешения → Известия.
  3. Променете предпочитанията си.
Chrome (Desktop)
  1. Кликнете върху иконата на катинар в адресната лента.
  2. Изберете Настройки на сайта.
  3. Намерете Известия и коригирайте предпочитанията си.