Консультация № 177491
27.03.2010, 19:46
0.00 руб.
0 11 1
Необходимо написать программу:
1) Программа считывает текст из файла и выводит на экран только слова, состоящие из заданного количества букв.
2) Сформировать из текста словарь (сортировка по алфавиту). Реализовать возможность дополнения словаря из других файлов
3) Реализовать возможность поиска по словарю, дополнение словаря отдельными словами.

Буду благодарен, если хоть чем-нибудь поможете. Желательно, чтобы работало в VS2008.

Обсуждение

Неизвестный
28.03.2010, 00:38
общий
atomi:
Уточните, какие средства можно применять, например, допустим ли stl.
Неизвестный
28.03.2010, 18:52
общий
Verena:
stl допустим.
Неизвестный
30.03.2010, 14:27
общий
1) Программа считывает текст из файла и выводит на экран только слова, состоящие из заданного количества букв.
Код:
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>


int main(int argc, char **argv)
{
if(argc!=3)
{
fprintf(stderr,"Use %s filename wordlen\n",argv[0]);
exit(1);
};
int fd=open(argv[1],O_RDONLY);
if(fd==-1)
{
fprintf(stderr,"Failed to open file: %s\n",argv[1]);
exit(1);
};

int len=0;
if(sscanf(argv[2],"%d",&len)!=1)
{
fprintf(stderr,"Use %s filename wordlen\n",argv[0]);
exit(1);
};

char buffer[256];
memset(&buffer,0,sizeof(buffer));
int ptr=0;
char c=0;
int matched=1;

while(1)
{
if(read(fd,&c,1)!=1)
{
exit(0);
};
matched=1;
if((c>='a' && c<='z')||(c>='A' && c<='Z'))
{
buffer[ptr]=c;
ptr++;
matched=0;
};
if(ptr==len && matched)
{
printf("%s\n",&buffer[0]);
};
if(ptr==256)
{
fprintf(stderr,"Buffer overflow\n");
memset(&buffer,0,sizeof(buffer));
ptr=0;
};
if(matched && ptr>0)
{
memset(&buffer,0,sizeof(buffer));
ptr=0;
}
}
return 0;
};


GCC/linux и mingw32 собирают, насчет vs2008 не знаю. Если будут ошибки, пишите в форум.
Попробую сделать и остальные, если получится, оформлю ответ.
Неизвестный
30.03.2010, 15:36
общий
2) Сформировать из текста словарь (сортировка по алфавиту). Реализовать возможность дополнения словаря из других файлов
3) Реализовать возможность поиска по словарю, дополнение словаря отдельными словами.
Код:
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>

struct dict_node
{
struct dict_node * children['z'-'A'];
struct dict_node * parent;
int final;
};

struct dict_node * find_word(struct dict_node * root,char * word)
{
if(root==NULL)return NULL;
if(word==NULL)return NULL;
struct dict_node * node=root;
int ptr=0;
while(ptr<strlen(word))
{
if(node->children[word[ptr]-'A']!=NULL)
{
node=node->children[word[ptr]-'A'];
}else return NULL;
++ptr;
};
if(node->final=1) return node;
return NULL;
};

int add_word(struct dict_node * root,char * word)
{
if(root==NULL)return -1;
if(word==NULL)return -1;
struct dict_node * res=find_word(root,word);
if(res!=NULL)return 0;
struct dict_node * node=root;
int ptr=0;
while(ptr<strlen(word))
{
if(node->children[word[ptr]-'A']!=NULL)
{
node=node->children[word[ptr]-'A'];
}else{
struct dict_node * new_node=calloc(sizeof(struct dict_node),1);
new_node->parent=node;
node->children[word[ptr]-'A']=new_node;
node=new_node;
};
++ptr;
};
node->final=1;
return 0;
};

char * write_buf=NULL;
char * write_buf_end=NULL;
char * write_ptr=NULL;
FILE * write_file=NULL;

void write_dict_r(struct dict_node * node)
{
if(node==NULL)return;
if(write_buf==NULL)return;
if(write_buf_end==NULL)return;
if(write_ptr==NULL)return;
if(write_file==NULL)return;
if(write_ptr==write_buf_end)
{
fprintf(stderr,"Warning: buffer overflow\n");
return;
}
if(node->final)
fprintf(write_file,"%s\n",write_buf);
int k;
for(k=0;k<'Z'-'A';k++)
{
if(node->children[k]!=NULL)
{
*write_ptr=k+'A';
++write_ptr;
write_dict_r(node->children[k]);
--write_ptr;
*write_ptr=0;
};
if(node->children[k+'a'-'A']!=NULL)
{
*write_ptr=k+'a';
++write_ptr;
write_dict_r(node->children[k+'a'-'A']);
--write_ptr;
*write_ptr=0;
};
}
};

void free_dict(struct dict_node * node)
{
int k;
for(k=0;k<'z'-'A';k++)
if(node->children[k]!=NULL)
free_dict(node->children[k]);
free(node);
};

void load_dict(struct dict_node * node,char *fname)
{
if(node==NULL)return;
FILE * f=fopen(fname,"r");
if(f==NULL)return;
char buffer[256];
memset(&buffer,0,sizeof(buffer));
while(fscanf(f,"%255s\n",&buffer[0])==1)
{
add_word(node,&buffer[0]);
memset(&buffer,0,sizeof(buffer));
};
fclose(f);
};

void save_dict(struct dict_node * node,char *fname)
{
if(node==NULL)return;
FILE * f=fopen(fname,"w");
if(f==NULL)return;
write_buf=calloc(256,1);
write_buf_end=write_buf+256;
write_ptr=write_buf;
write_file=f;
write_dict_r(node);
fclose(f);
};


void add_file(struct dict_node * node,char *fname)
{
if(node==NULL)return;
int fd=open(fname,O_RDONLY);
if(fd==-1)
{
fprintf(stderr,"Failed to open file: %s\n",fname);
return;
};

char buffer[256];
memset(&buffer,0,sizeof(buffer));
int ptr=0;
char c=0;
int matched=1;

while(1)
{
if(read(fd,&c,1)!=1)
{
close(fd);
return;
};
matched=1;
if((c>='a' && c<='z')||(c>='A' && c<='Z'))
{
buffer[ptr]=c;
ptr++;
matched=0;
};
if(ptr==256)
{
fprintf(stderr,"Buffer overflow\n");
memset(&buffer,0,sizeof(buffer));
ptr=0;
};
if(matched && ptr>0)
{
add_word(node,&buffer[0]);
memset(&buffer,0,sizeof(buffer));
ptr=0;
}
}
close(fd);
};









void usage(char **argv)
{
fprintf(stderr,"Use %s -f filename\n",argv[0]);
fprintf(stderr,"Use %s -w add_word\n",argv[0]);
fprintf(stderr,"Use %s -l lookup_word\n",argv[0]);
};



int main(int argc, char **argv)
{
if(argc!=3)
{
usage(argv);
exit(1);
};
if(argv[1][0]!='-')
{
usage(argv);
exit(1);
};

struct dict_node * dict=calloc(sizeof(struct dict_node),1);

switch(argv[1][1])
{
case 'f':
load_dict(dict,"dictionary");
add_file(dict,argv[2]);
save_dict(dict,"dictionary");
break;
case 'w':
load_dict(dict,"dictionary");
add_word(dict,argv[2]);
save_dict(dict,"dictionary");
break;
case 'l':
load_dict(dict,"dictionary");
if(find_word(dict,argv[2])!=NULL)
{
printf("Word "%s" found in dictionary.\n",argv[2]);
}else{
printf("Word "%s" not found in dictionary.\n",argv[2]);
};
break;
};
return 0;





};









В общем так как-то. Был один Segmentation fault при первом запуске, так что могут быть баги. Возможно неинициализированная переменная...
Если устраивает, делаю ответ.

Неизвестный
30.03.2010, 16:44
общий
это ответ
Здравствуйте, atomi.
1) Программа считывает текст из файла и выводит на экран только слова, состоящие из заданного количества букв.
Код:
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>


int main(int argc, char **argv)
{
if(argc!=3)
{
fprintf(stderr,"Use %s filename wordlen\n",argv[0]);
exit(1);
};
int fd=open(argv[1],O_RDONLY);
if(fd==-1)
{
fprintf(stderr,"Failed to open file: %s\n",argv[1]);
exit(1);
};

int len=0;
if(sscanf(argv[2],"%d",&len)!=1)
{
fprintf(stderr,"Use %s filename wordlen\n",argv[0]);
exit(1);
};

char buffer[256];
memset(&buffer,0,sizeof(buffer));
int ptr=0;
char c=0;
int matched=1;

while(1)
{
if(read(fd,&c,1)!=1)
{
exit(0);
};
matched=1;
if((c>='a' && c<='z')||(c>='A' && c<='Z'))
{
buffer[ptr]=c;
ptr++;
matched=0;
};
if(ptr==len && matched)
{
printf("%s\n",&buffer[0]);
};
if(ptr==256)
{
fprintf(stderr,"Buffer overflow\n");
memset(&buffer,0,sizeof(buffer));
ptr=0;
};
if(matched && ptr>0)
{
memset(&buffer,0,sizeof(buffer));
ptr=0;
}
}
return 0;
};


Во вложении
2) Сформировать из текста словарь (сортировка по алфавиту). Реализовать возможность дополнения словаря из других файлов
3) Реализовать возможность поиска по словарю, дополнение словаря отдельными словами.

Если будут проблемы при сборке/запуске, пишите, попробую исправить.

Приложение:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct dict_node
{
struct dict_node * children['z'-'A'];
struct dict_node * parent;
int final;
};

struct dict_node * find_word(struct dict_node * root,char * word)
{
if(root==NULL)return NULL;
if(word==NULL)return NULL;
struct dict_node * node=root;
int ptr=0;
while(ptr<strlen(word))
{
if(node->children[word[ptr]-'A']!=NULL)
{
node=node->children[word[ptr]-'A'];
}else return NULL;
++ptr;
};
if(node->final=1) return node;
return NULL;
};

int add_word(struct dict_node * root,char * word)
{
if(root==NULL)return -1;
if(word==NULL)return -1;
struct dict_node * res=find_word(root,word);
if(res!=NULL)return 0;
struct dict_node * node=root;
int ptr=0;
while(ptr<strlen(word))
{
if(node->children[word[ptr]-'A']!=NULL)
{
node=node->children[word[ptr]-'A'];
}else{
struct dict_node * new_node=calloc(sizeof(struct dict_node),1);
new_node->parent=node;
node->children[word[ptr]-'A']=new_node;
node=new_node;
};
++ptr;
};
node->final=1;
return 0;
};

char * write_buf=NULL;
char * write_buf_end=NULL;
char * write_ptr=NULL;
FILE * write_file=NULL;

void write_dict_r(struct dict_node * node)
{
if(node==NULL)return;
if(write_buf==NULL)return;
if(write_buf_end==NULL)return;
if(write_ptr==NULL)return;
if(write_file==NULL)return;
if(write_ptr==write_buf_end)
{
fprintf(stderr,"Warning: buffer overflow\n");
return;
}
if(node->final)
fprintf(write_file,"%s\n",write_buf);
int k;
for(k=0;k<'Z'-'A';k++)
{
if(node->children[k]!=NULL)
{
*write_ptr=k+'A';
++write_ptr;
write_dict_r(node->children[k]);
--write_ptr;
*write_ptr=0;
};
if(node->children[k+'a'-'A']!=NULL)
{
*write_ptr=k+'a';
++write_ptr;
write_dict_r(node->children[k+'a'-'A']);
--write_ptr;
*write_ptr=0;
};
}
};

void free_dict(struct dict_node * node)
{
int k;
for(k=0;k<'z'-'A';k++)
if(node->children[k]!=NULL)
free_dict(node->children[k]);
free(node);
};

void load_dict(struct dict_node * node,char *fname)
{
if(node==NULL)return;
FILE * f=fopen(fname,"r");
if(f==NULL)return;
char buffer[256];
memset(&buffer,0,sizeof(buffer));
while(fscanf(f,"%255s\n",&buffer[0])==1)
{
add_word(node,&buffer[0]);
memset(&buffer,0,sizeof(buffer));
};
fclose(f);
};

void save_dict(struct dict_node * node,char *fname)
{
if(node==NULL)return;
FILE * f=fopen(fname,"w");
if(f==NULL)return;
write_buf=calloc(256,1);
write_buf_end=write_buf+256;
write_ptr=write_buf;
write_file=f;
write_dict_r(node);
fclose(f);
};


void add_file(struct dict_node * node,char *fname)
{
if(node==NULL)return;
FILE * f=fopen(fname,"r");
if(f==NULL)
{
fprintf(stderr,"Failed to open file: %s\n",fname);
return;
};

char buffer[256];
memset(&buffer,0,sizeof(buffer));
int ptr=0;
char c=0;
int matched=1;

while(1)
{
if(fread(&c,1,1,f)!=1)
{
fclose(f);
return;
};
matched=1;
if((c>='a' && c<='z')||(c>='A' && c<='Z'))
{
buffer[ptr]=c;
ptr++;
matched=0;
};
if(ptr==256)
{
fprintf(stderr,"Buffer overflow\n");
memset(&buffer,0,sizeof(buffer));
ptr=0;
};
if(matched && ptr>0)
{
add_word(node,&buffer[0]);
memset(&buffer,0,sizeof(buffer));
ptr=0;
}
}
fclose(f);
};









void usage(char **argv)
{
fprintf(stderr,"Use %s -f filename\n",argv[0]);
fprintf(stderr,"Use %s -w add_word\n",argv[0]);
fprintf(stderr,"Use %s -l lookup_word\n",argv[0]);
};



int main(int argc, char **argv)
{
if(argc!=3)
{
usage(argv);
exit(1);
};
if(argv[1][0]!='-')
{
usage(argv);
exit(1);
};

struct dict_node * dict=calloc(sizeof(struct dict_node),1);

switch(argv[1][1])
{
case 'f':
load_dict(dict,"dictionary");
add_file(dict,argv[2]);
save_dict(dict,"dictionary");
break;
case 'w':
load_dict(dict,"dictionary");
add_word(dict,argv[2]);
save_dict(dict,"dictionary");
break;
case 'l':
load_dict(dict,"dictionary");
if(find_word(dict,argv[2])!=NULL)
{
printf("Word "%s" found in dictionary.\n",argv[2]);
}else{
printf("Word "%s" not found in dictionary.\n",argv[2]);
};
break;
};
return 0;

};
Неизвестный
11.04.2010, 12:46
общий
При компиляции VS 2008 выдаёт ошибки:
error C3861: open: идентификатор не найден
error C3861: read: идентификатор не найден
Неизвестный
12.04.2010, 11:08
общий
atomi:
В венде нет системного вызова open. Там надо CreateFileW(argv[1],GENERIC_READ,...) ...
Поменял на stream io:
Код:
diff --git a/words.c b/words.c
index 659504a..f520eff 100644
--- a/words.c
+++ b/words.c
@@ -11,8 +11,8 @@ int main(int argc, char **argv)
fprintf(stderr,"Use %s filename wordlen\n",argv[0]);
exit(1);
};
- int fd=open(argv[1],O_RDONLY);
- if(fd==-1)
+ FILE* fd=fopen(argv[1],"r");
+ if(fd==NULL)
{
fprintf(stderr,"Failed to open file: %s\n",argv[1]);
exit(1);
@@ -33,7 +33,7 @@ int main(int argc, char **argv)

while(1)
{
- if(read(fd,&c,1)!=1)
+ if(fread(&c,1,1,fd)!=1)
{
exit(0);
};
@@ -60,6 +60,7 @@ int main(int argc, char **argv)
ptr=0;
}
}
+ fclose(fd);
return 0;
};

теперь должно собраться.
Неизвестный
18.04.2010, 22:54
общий
vladisslav:
А можно, например, идентификаторы open и read заменить чем-нибудь другим?
Неизвестный
19.04.2010, 11:57
общий
Цитата: 325681
А можно, например, идентификаторы open и read заменить чем-нибудь другим?

Не понял. Поменял же. Вы патч применяли/читали?
Неизвестный
20.04.2010, 17:57
общий
Да посмотрел, но не понял как пользоваться. Что за @@ -11,8 +11,8 @@ и +,-, мне, к сожалению не понятно.
Неизвестный
21.04.2010, 09:36
общий
Цитата: 325681
Да посмотрел, но не понял как пользоваться


Объясняю:
-удалить строку
+вставить строку
@@ -11,8 +11,8 @@
-11 - номер строки в исходном файле
,8 - количество строк в исходном файле (вместе с неизменяемыми)
+11 - номер строки в конечном файле
,8 - аналогично количество строк в конечном файле
строки без +/- в начале не изменяются патчем, а используются для проверки нахождения изменяемого фрагмента (патч можно накладывать на файлы, измененные в других местах)
Форма ответа