Консультация № 173589
22.10.2009, 23:44
25.00 руб.
0 8 1
Добрый вечер, уважаемые эксперты! Решите пожалуйста эту задачу.

Написать программу - эмулятор системы Т9 мобильного телефона. Символы должны набираться нажатием цифр на клавиатуре компьютера. Расположение и соответствие букв цифрам должно быть такое же, как и на мобильном телефоне. Программа должна предлагать варианты слов. Должна быть предусмотрена возможность добавления новых слов и возможность нескольких словарей (для разных языков).

За ранее благодарю!

Обсуждение

Неизвестный
24.10.2009, 03:06
общий
Набросал по быстрому сокращенную реализацию.
Если устроит, могу добавить русские комментарии и сделать ответ.
Код:
/*
This is free software;
you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <time.h>


#define MAX_WORD_LEN 1024

char * dig2char[10];
char char2dig[256];

void fill_en()
{
dig2char[0]=" 0";
dig2char[1]=".,?!'"1()@/:-";
dig2char[2]="abc2";
dig2char[3]="def3";
dig2char[4]="ghi4";
dig2char[5]="jkl5";
dig2char[6]="mno6";
dig2char[7]="pqrs7";
dig2char[8]="tuv8";
dig2char[9]="wxyz9";
int k;
for(k=0;k<256;k++)
{
char2dig[k]=-1;
};
int t,l;
for(k=0;k<10;k++)
{
l=strlen(dig2char[k]);
for(t=0;t<l;t++)
{
char2dig[dig2char[k][t]]=k;
};
};
};


struct dict_word
{
struct dict_word * next;
char * word;
};

struct dict_node
{
int word_count;
struct dict_word * words;
struct dict_node * next[10];
};

add_to_dict(struct dict_node ** dict,char *str)
{
char * pc=str;
int ln=strlen(str);
char * pe=str+ln;
struct dict_node *pd;
if(ln>0 && *dict == NULL)
{
*dict = calloc(1,sizeof(struct dict_node));
};
pd=*dict;
while(pc<pe)
{
if(pd->next[char2dig[*pc]] == NULL)
pd->next[char2dig[*pc]]=calloc(1,sizeof(struct dict_node));
pd=pd->next[char2dig[*pc]];
pc++;
};
struct dict_word * new_word;
if(pd->words==NULL)
new_word=pd->words=calloc(1,sizeof(struct dict_word));
else{
new_word=pd->words;
while(new_word->next != NULL)
if(strcmp(new_word->word,str)==0)return;
else new_word=new_word->next;
new_word->next=calloc(1,sizeof(struct dict_word));
new_word=new_word->next;
};
new_word->word=calloc(1,ln+1);
strcpy(new_word->word,str);
pd->word_count++;
};


void save_dictionary_fd(struct dict_node * dict,FILE * fd)
{
if(dict==NULL)return;
struct dict_word * word=dict->words;
while(word != NULL)
{
fprintf(fd,"%s\n",word->word);
word=word->next;
};
int k;
for(k=0;k<10;k++)save_dictionary_fd(dict->next[k],fd);
};

int save_dictionary(struct dict_node * dict,char *file_name)
{
FILE * fd=fopen(file_name,"w");
if(fd==NULL)return -1;
save_dictionary_fd(dict,fd);
fclose(fd);
return 0;
};

struct dict_node * load_dictionary(char *file_name)
{
struct dict_node * tmp=NULL;
char buffer[MAX_WORD_LEN];
FILE * fd=fopen(file_name,"r");
if(fd==NULL)return NULL;

while(fscanf(fd,"%s",&buffer)==1)
{
add_to_dict(& tmp,&buffer[0]);
memset(&buffer,0,sizeof(buffer));
};
fclose(fd);
return tmp;
};

struct dict_node * find_dict_node(struct dict_node * dict,char * seq)
{
struct dict_node *pd=dict;
if(pd==NULL)return NULL;
char *pc=seq;
char *pe=seq+strlen(seq);
while(pc<pe && pd != NULL)
{
pd=pd->next[*pc -'0'];
pc++;
};
return pd;
};

struct dict_word * any_word(struct dict_node * dict)
{
struct dict_node *pd=dict;
if(pd==NULL)return NULL;
if(pd->words != NULL)return pd->words;
int k;
struct dict_word *tmp=NULL;
for(k=0;k<10;k++)
if(pd->next[k]!=NULL)
if((tmp=any_word(pd->next[k])) != NULL)return tmp;
return NULL;

};

struct dict_word * find_part_word(struct dict_node * dict,char * seq)
{
struct dict_node *pd=dict;
if(pd==NULL)return NULL;
char *pc=seq;
char *pe=seq+strlen(seq);
while(pc<pe && pd != NULL)
{
pd=pd->next[*pc -'0'];
pc++;
};
if(pd==NULL)return NULL;
return pd->words;
};

void cleanline(struct dict_word *ls,char*add)
{
int len=0;
struct dict_word *lp=ls;
while(lp != NULL)
{
len+=strlen(lp->word);
lp=lp->next;
};
if(len<12)len=12;
len+=strlen(add);
char * buf=calloc(1,len+1);
memset(buf,32,len);
fprintf(stderr,"\r%s",buf);
free(buf);
};

summary()
{
fprintf(stderr,"T9 like input demo.\n");
fprintf(stderr,"\n");
fprintf(stderr,"2-9 - input letters using dictionary.\n");
fprintf(stderr,"1 - input symbols/submit word.\n");
fprintf(stderr,"0 - input space/submit word.\n");
fprintf(stderr,"* - search dictionary for entered sequence of digits.\n");
fprintf(stderr,". - delete last char (does not work for submitted words/spaces/symbols for now.\n");
fprintf(stderr,"\n");
fprintf(stderr,"If sequence has no valid dictionary match input mode will switch to cycle-through-letter-with-delay.\n");
fprintf(stderr,"This will be indicated with "by letters" prompt.\n");
fprintf(stderr,"0-9 - input letters/digits/symbols.\n");
fprintf(stderr,"* - submit and store new word in dictionary/return if empty.\n");
fprintf(stderr,". - delete last char.\n");
fprintf(stderr,"Delay is around 1-2 seconds. Then the same digit will advance to next letter.\n");
fprintf(stderr,"\n");
fprintf(stderr,"Hit Enter to quit.\n");



};


int main()
{
summary();
char buf,indx;
char word[MAX_WORD_LEN];
struct dict_word * word_list=NULL;
struct dict_word * word_last=NULL;
char *current=&word[0];
char t9buffer[MAX_WORD_LEN];
char *pt9=&t9buffer[0];
char *dict_file="dict";
int k;
for(k=0;k<sizeof(word);k++)word[k]=0;
for(k=0;k<sizeof(word);k++)t9buffer[k]=0;
fill_en();
struct dict_node * dict=load_dictionary(dict_file);
fprintf(stderr,"\n");
/*set up terminal*/
struct termios term,old;
tcgetattr(fileno(stdin),&term);
tcgetattr(fileno(stdin),&old);

term.c_lflag &= ~ICANON;
term.c_lflag &= ~ECHO;
tcsetattr(fileno(stdin),0,&term);

/*timing*/
time_t prev,now,in_delay;
prev=time(NULL);
now=prev;

struct dict_word * found_word=NULL;
struct dict_node *dn=NULL;
int started=0;
int mode=1;
int symbols=0;
while(1)
{
//buf=fgetc(stdin);read(stdin,&buf,1);
buf=getchar();
now=time(NULL);
in_delay=now-prev;
if(!started)in_delay=0;
prev=now;

if(mode==0 || mode==2)//raw
{
started=1;
if(buf>='0' && buf<='9')
{

indx=buf-'0';
if(in_delay>=2)current++;
if(char2dig[*current]!=indx && *current!=0)current++;
if(*current==0)
*current=dig2char[indx][0];
else
{
int k,l;
l=strlen(dig2char[indx]);
for(k=0;k<l;k++)
{
if(dig2char[indx][k]==*current && k+1<l)
{
*current=dig2char[indx][k+1];
break;
};
if(dig2char[indx][k]==*current && k+1==l)
{
*current=dig2char[indx][0];
break;
};
}
};
if(mode==2 && indx==0) *current = '0';
if(mode==2 && indx==1) *current = '1';
};
if(buf==127 || buf==8 || buf=='.')
{
if(*current != 0)
{
*current=0;
if(current > &word[0])
{
current--;
prev-=2;
}else started=0;
};
fprintf(stderr,"\033[1D ");
//fprintf(stderr,"\r ");
};
if(mode==2 && buf=='*')
{
/*finish editing*/
if(strlen(word)>0)
{
if(word_list==NULL)
{
word_list=calloc(1,sizeof(struct dict_word));
word_last=word_list;
}else{
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
};
word_last->word=calloc(1,strlen(word)+1);
strcpy(word_last->word,&word[0]);
add_to_dict(&dict,word_last->word);
save_dictionary(dict,dict_file);
};
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
current=&word[0];
mode=1;
buf=0;
};
};

if(mode==1)//dict
{
started=0;
int changed=0;
if(buf=='0')
{
//finish word if not possible or switch to 2
if(symbols)
{
if(word_list==NULL)
{
word_list=calloc(1,sizeof(struct dict_word));
word_last=word_list;
}else{
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
};
word_last->word=calloc(1,2);
strcpy(word_last->word,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
symbols=0;
}else{
if(dn == NULL)
{
if(strlen(t9buffer)>0)
{
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
current=&word[0];
mode=2;
};
}else{
if(word_list==NULL)
{
word_list=calloc(1,sizeof(struct dict_word));
word_last=word_list;
}else{
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
};

if(dn->words != NULL)
{
word_last->word=found_word->word;
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
}else{
//submit partial word, add to dict
word_last->word=calloc(1,strlen(t9buffer)+1);
strcpy(word_last->word,&word[0]);
add_to_dict(&dict,word_last->word);
save_dictionary(dict,dict_file);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
};
};
};
if(mode==1)
{
//add space
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
word_last->word=" ";
};
};
if(buf=='1')
{
if(symbols)
{
int k,l;
l=strlen(dig2char[1]);
for(k=0;k<l;k++)
{
if(dig2char[1][k]==*current && k+1<l)
{
*current=dig2char[1][k+1];
if(*current=='1')*current=dig2char[1][k+2];
break;
};
if(dig2char[1][k]==*current && k+1==l)
{
*current=dig2char[1][0];
break;
};
};
changed=1;
}else{
symbols=1;
if(dn == NULL)
{
if(strlen(t9buffer)>0)
{
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
current=&word[0];
mode=2;
};
}else{
if(word_list==NULL)
{
word_list=calloc(1,sizeof(struct dict_word));
word_last=word_list;
}else{
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
};
if(dn->words != NULL)
{
word_last->word=found_word->word;
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
}else{
//submit partial word, add to dict
word_last->word=calloc(1,strlen(t9buffer)+1);
strcpy(word_last->word,&word[0]);
add_to_dict(&dict,word_last->word);
save_dictionary(dict,dict_file);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
};
};
if(mode==1)
{
word[0]=dig2char[1][0];
};
};
};
if(buf>='2' && buf<='9')
{
if(symbols)
{
if(word_list==NULL)
{
word_list=calloc(1,sizeof(struct dict_word));
word_last=word_list;
}else{
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
};
word_last->word=calloc(1,2);
strcpy(word_last->word,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
symbols=0;
};
*pt9=buf;
pt9++;
changed=1;
};
if(buf=='*' && !symbols)
{
if(found_word!=NULL)found_word=found_word->next;
if(found_word==NULL)
{
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
current=&word[0];
mode=2;
};
};
if(buf==127 || buf==8 || buf=='.')
{
if(pt9 > &t9buffer[0])pt9--;
*pt9=0;
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
fprintf(stderr,"%c ",127);
changed=1;
symbols=0;
};
if(changed)
{
changed=0;
dn=find_dict_node(dict,&t9buffer[0]);
if(dn==NULL)
{
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
current=&word[0];
mode=2;
}else{
if(dn->words==NULL)
{
found_word=any_word(dn);
}else{
found_word=dn->words;
};
};
if(found_word==NULL)
{
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
pt9=&t9buffer[0];
current=&word[0];
mode=2;
};
};
if(found_word != NULL)
{
strncpy(&word[0],found_word->word,strlen(&t9buffer[0]));
};
};

if(buf==10)
{
tcsetattr(fileno(stdin),0,&old);
fprintf(stderr,"\n");
exit(0);
};
fprintf(stderr,"\r");
if(mode==2)fprintf(stderr,"by letters :");
else
if(word_list != NULL)
{
struct dict_word * tmp=word_list;
while(tmp != NULL)
{
fprintf(stderr,"%s",tmp->word);
tmp=tmp->next;
};
};
fprintf(stderr,"%s",&word);
};



return 0;
};





Если будет свободное время, добавлю удаление слов и курсорные клавиши.
Для сборки нужна поддержка POSIX.1-2001 компилятором. Для работы нужен ANSI терминал.
давно
Старший Модератор
17042
808
24.10.2009, 08:08
общий
vladisslav:
А почему не подали код из Вашего поста как ответ? Это положительно сказалось бы как на Вашем рейтинге, так и на рейтинге рассылки в целом. А мини-форум это так, обсуждение. Впрочем, время для подачи ответа ещё есть...
Об авторе:
We have but faith: we cannot know;
For knowledge is of things we see;
And yet we trust it comes from thee,
A beam in darkness: let it grow.
-----
https://www.linkedin.com/in/andreynkuznetsov
https://www.researchgate.net/profile/Andrey_Kuznetsov11
http://www.researcherid.com/rid/K-8824-2014
Неизвестный
24.10.2009, 16:48
общий
Если не затруднит - сделайте пожалуйста=)
Неизвестный
25.10.2009, 03:11
общий
это ответ
Здравствуйте, Андреев Юрий Николаевич.
Времени пока особо нет, так что делаю ответом тот простенький вариант из первого комментария.
В режиме словаря
2-9 - ввод букв с автоматическим выбором из словаря
* - перебор вариантов, после последнего варианта переключение в режим побуквенного ввода
. - удаление последнего символа
1 - ввод знаков и подтверждение введенного слова
0 - пробел и подтверждение введенного слова
В режиме побуквенного ввода
0-9 - ввод букв и цифр, переход к следующей позиции с 1-2секундной задержкой/по нажатию другой цифры сразу
. - удаление последнего символа
* - подтверждение и добавление в словарь
Словарь лежит в файле dict по одному слову на строчке, предполагается ASCII
Для изменения языка ввода нужно поменять сопоставление цифр/букв (функция fill_en(), сделать еще одну по аналогии) и загрузить словарь из другого файла поменять dict_file и вызвать dict=load_dictionary(dict_file);, предварительно желательно удлить старый словарь, так как будут утечки.
Словарь - обычное b+ дерево,поле word_count можно убрать, так как не используется.
Алгоритм возможно запатентован в некоторых странах, так что в случае экспорта оборудования нужно поискать патенты и при необходимости купить лицензию/произвести отчисления.
Переключения языков, юникод, удаление слов, буквы в разных регистрах и перемещение курсора может быть сделаю позже, так как тема интересная и может пригодиться в своих железках.

Приложение:
/*
This is free software;
you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <time.h>


#define MAX_WORD_LEN 1024

char * dig2char[10];
char char2dig[256];

void fill_en()
{
dig2char[0]=" 0";
dig2char[1]=".,?!'"1()@/:-";
dig2char[2]="abc2";
dig2char[3]="def3";
dig2char[4]="ghi4";
dig2char[5]="jkl5";
dig2char[6]="mno6";
dig2char[7]="pqrs7";
dig2char[8]="tuv8";
dig2char[9]="wxyz9";
int k;
for(k=0;k<256;k++)
{
char2dig[k]=-1;
};
int t,l;
for(k=0;k<10;k++)
{
l=strlen(dig2char[k]);
for(t=0;t<l;t++)
{
char2dig[dig2char[k][t]]=k;
};
};
};


struct dict_word
{
struct dict_word * next;
char * word;
};

struct dict_node
{
int word_count;
struct dict_word * words;
struct dict_node * next[10];
};

add_to_dict(struct dict_node ** dict,char *str)
{
char * pc=str;
int ln=strlen(str);
char * pe=str+ln;
struct dict_node *pd;
if(ln>0 && *dict == NULL)
{
*dict = calloc(1,sizeof(struct dict_node));
};
pd=*dict;
while(pc<pe)
{
if(pd->next[char2dig[*pc]] == NULL)
pd->next[char2dig[*pc]]=calloc(1,sizeof(struct dict_node));
pd=pd->next[char2dig[*pc]];
pc++;
};
struct dict_word * new_word;
if(pd->words==NULL)
new_word=pd->words=calloc(1,sizeof(struct dict_word));
else{
new_word=pd->words;
while(new_word->next != NULL)
if(strcmp(new_word->word,str)==0)return;
else new_word=new_word->next;
new_word->next=calloc(1,sizeof(struct dict_word));
new_word=new_word->next;
};
new_word->word=calloc(1,ln+1);
strcpy(new_word->word,str);
pd->word_count++;
};


void save_dictionary_fd(struct dict_node * dict,FILE * fd)
{
if(dict==NULL)return;
struct dict_word * word=dict->words;
while(word != NULL)
{
fprintf(fd,"%s\n",word->word);
word=word->next;
};
int k;
for(k=0;k<10;k++)save_dictionary_fd(dict->next[k],fd);
};

int save_dictionary(struct dict_node * dict,char *file_name)
{
FILE * fd=fopen(file_name,"w");
if(fd==NULL)return -1;
save_dictionary_fd(dict,fd);
fclose(fd);
return 0;
};

struct dict_node * load_dictionary(char *file_name)
{
struct dict_node * tmp=NULL;
char buffer[MAX_WORD_LEN];
FILE * fd=fopen(file_name,"r");
if(fd==NULL)return NULL;

while(fscanf(fd,"%s",&buffer)==1)
{
add_to_dict(& tmp,&buffer[0]);
memset(&buffer,0,sizeof(buffer));
};
fclose(fd);
return tmp;
};

struct dict_node * find_dict_node(struct dict_node * dict,char * seq)
{
struct dict_node *pd=dict;
if(pd==NULL)return NULL;
char *pc=seq;
char *pe=seq+strlen(seq);
while(pc<pe && pd != NULL)
{
pd=pd->next[*pc -'0'];
pc++;
};
return pd;
};

struct dict_word * any_word(struct dict_node * dict)
{
struct dict_node *pd=dict;
if(pd==NULL)return NULL;
if(pd->words != NULL)return pd->words;
int k;
struct dict_word *tmp=NULL;
for(k=0;k<10;k++)
if(pd->next[k]!=NULL)
if((tmp=any_word(pd->next[k])) != NULL)return tmp;
return NULL;

};

struct dict_word * find_part_word(struct dict_node * dict,char * seq)
{
struct dict_node *pd=dict;
if(pd==NULL)return NULL;
char *pc=seq;
char *pe=seq+strlen(seq);
while(pc<pe && pd != NULL)
{
pd=pd->next[*pc -'0'];
pc++;
};
if(pd==NULL)return NULL;
return pd->words;
};

void cleanline(struct dict_word *ls,char*add)
{
int len=0;
struct dict_word *lp=ls;
while(lp != NULL)
{
len+=strlen(lp->word);
lp=lp->next;
};
if(len<12)len=12;
len+=strlen(add);
char * buf=calloc(1,len+1);
memset(buf,32,len);
fprintf(stderr,"\r%s",buf);
free(buf);
};

summary()
{
fprintf(stderr,"T9 like input demo.\n");
fprintf(stderr,"\n");
fprintf(stderr,"2-9 - input letters using dictionary.\n");
fprintf(stderr,"1 - input symbols/submit word.\n");
fprintf(stderr,"0 - input space/submit word.\n");
fprintf(stderr,"* - search dictionary for entered sequence of digits.\n");
fprintf(stderr,". - delete last char (does not work for submitted words/spaces/symbols for now.\n");
fprintf(stderr,"\n");
fprintf(stderr,"If sequence has no valid dictionary match input mode will switch to cycle-through-letter-with-delay.\n");
fprintf(stderr,"This will be indicated with "by letters" prompt.\n");
fprintf(stderr,"0-9 - input letters/digits/symbols.\n");
fprintf(stderr,"* - submit and store new word in dictionary/return if empty.\n");
fprintf(stderr,". - delete last char.\n");
fprintf(stderr,"Delay is around 1-2 seconds. Then the same digit will advance to next letter.\n");
fprintf(stderr,"\n");
fprintf(stderr,"Hit Enter to quit.\n");



};


int main()
{
summary();
char buf,indx;
char word[MAX_WORD_LEN];
struct dict_word * word_list=NULL;
struct dict_word * word_last=NULL;
char *current=&word[0];
char t9buffer[MAX_WORD_LEN];
char *pt9=&t9buffer[0];
char *dict_file="dict";
int k;
for(k=0;k<sizeof(word);k++)word[k]=0;
for(k=0;k<sizeof(word);k++)t9buffer[k]=0;
fill_en();
struct dict_node * dict=load_dictionary(dict_file);
fprintf(stderr,"\n");
/*set up terminal*/
struct termios term,old;
tcgetattr(fileno(stdin),&term);
tcgetattr(fileno(stdin),&old);

term.c_lflag &= ~ICANON;
term.c_lflag &= ~ECHO;
tcsetattr(fileno(stdin),0,&term);

/*timing*/
time_t prev,now,in_delay;
prev=time(NULL);
now=prev;

struct dict_word * found_word=NULL;
struct dict_node *dn=NULL;
int started=0;
int mode=1;
int symbols=0;
while(1)
{
//buf=fgetc(stdin);read(stdin,&buf,1);
buf=getchar();
now=time(NULL);
in_delay=now-prev;
if(!started)in_delay=0;
prev=now;

if(mode==0 || mode==2)//raw
{
started=1;
if(buf>='0' && buf<='9')
{

indx=buf-'0';
if(in_delay>=2)current++;
if(char2dig[*current]!=indx && *current!=0)current++;
if(*current==0)
*current=dig2char[indx][0];
else
{
int k,l;
l=strlen(dig2char[indx]);
for(k=0;k<l;k++)
{
if(dig2char[indx][k]==*current && k+1<l)
{
*current=dig2char[indx][k+1];
break;
};
if(dig2char[indx][k]==*current && k+1==l)
{
*current=dig2char[indx][0];
break;
};
}
};
if(mode==2 && indx==0) *current = '0';
if(mode==2 && indx==1) *current = '1';
};
if(buf==127 || buf==8 || buf=='.')
{
if(*current != 0)
{
*current=0;
if(current > &word[0])
{
current--;
prev-=2;
}else started=0;
};
fprintf(stderr,"\033[1D ");
//fprintf(stderr,"\r ");
};
if(mode==2 && buf=='*')
{
/*finish editing*/
if(strlen(word)>0)
{
if(word_list==NULL)
{
word_list=calloc(1,sizeof(struct dict_word));
word_last=word_list;
}else{
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
};
word_last->word=calloc(1,strlen(word)+1);
strcpy(word_last->word,&word[0]);
add_to_dict(&dict,word_last->word);
save_dictionary(dict,dict_file);
};
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
current=&word[0];
mode=1;
buf=0;
};
};

if(mode==1)//dict
{
started=0;
int changed=0;
if(buf=='0')
{
//finish word if not possible or switch to 2
if(symbols)
{
if(word_list==NULL)
{
word_list=calloc(1,sizeof(struct dict_word));
word_last=word_list;
}else{
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
};
word_last->word=calloc(1,2);
strcpy(word_last->word,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
symbols=0;
}else{
if(dn == NULL)
{
if(strlen(t9buffer)>0)
{
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
current=&word[0];
mode=2;
};
}else{
if(word_list==NULL)
{
word_list=calloc(1,sizeof(struct dict_word));
word_last=word_list;
}else{
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
};

if(dn->words != NULL)
{
word_last->word=found_word->word;
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
}else{
//submit partial word, add to dict
word_last->word=calloc(1,strlen(t9buffer)+1);
strcpy(word_last->word,&word[0]);
add_to_dict(&dict,word_last->word);
save_dictionary(dict,dict_file);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
};
};
};
if(mode==1)
{
//add space
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
word_last->word=" ";
};
};
if(buf=='1')
{
if(symbols)
{
int k,l;
l=strlen(dig2char[1]);
for(k=0;k<l;k++)
{
if(dig2char[1][k]==*current && k+1<l)
{
*current=dig2char[1][k+1];
if(*current=='1')*current=dig2char[1][k+2];
break;
};
if(dig2char[1][k]==*current && k+1==l)
{
*current=dig2char[1][0];
break;
};
};
changed=1;
}else{
symbols=1;
if(dn == NULL)
{
if(strlen(t9buffer)>0)
{
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
current=&word[0];
mode=2;
};
}else{
if(word_list==NULL)
{
word_list=calloc(1,sizeof(struct dict_word));
word_last=word_list;
}else{
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
};
if(dn->words != NULL)
{
word_last->word=found_word->word;
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
}else{
//submit partial word, add to dict
word_last->word=calloc(1,strlen(t9buffer)+1);
strcpy(word_last->word,&word[0]);
add_to_dict(&dict,word_last->word);
save_dictionary(dict,dict_file);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
};
};
if(mode==1)
{
word[0]=dig2char[1][0];
};
};
};
if(buf>='2' && buf<='9')
{
if(symbols)
{
if(word_list==NULL)
{
word_list=calloc(1,sizeof(struct dict_word));
word_last=word_list;
}else{
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
};
word_last->word=calloc(1,2);
strcpy(word_last->word,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
symbols=0;
};
*pt9=buf;
pt9++;
changed=1;
};
if(buf=='*' && !symbols)
{
if(found_word!=NULL)found_word=found_word->next;
if(found_word==NULL)
{
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
current=&word[0];
mode=2;
};
};
if(buf==127 || buf==8 || buf=='.')
{
if(pt9 > &t9buffer[0])pt9--;
*pt9=0;
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
fprintf(stderr,"%c ",127);
changed=1;
symbols=0;
};
if(changed)
{
changed=0;
dn=find_dict_node(dict,&t9buffer[0]);
if(dn==NULL)
{
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
current=&word[0];
mode=2;
}else{
if(dn->words==NULL)
{
found_word=any_word(dn);
}else{
found_word=dn->words;
};
};
if(found_word==NULL)
{
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
pt9=&t9buffer[0];
current=&word[0];
mode=2;
};
};
if(found_word != NULL)
{
strncpy(&word[0],found_word->word,strlen(&t9buffer[0]));
};
};

if(buf==10)
{
tcsetattr(fileno(stdin),0,&old);
fprintf(stderr,"\n");
exit(0);
};
fprintf(stderr,"\r");
if(mode==2)fprintf(stderr,"by letters :");
else
if(word_list != NULL)
{
struct dict_word * tmp=word_list;
while(tmp != NULL)
{
fprintf(stderr,"%s",tmp->word);
tmp=tmp->next;
};
};
fprintf(stderr,"%s",&word);
};



return 0;
};



5
давно
Профессор
230118
3054
28.10.2009, 15:14
общий
vladisslav:
А что это за termios.h? Это же не стандартный хедер, надо было его привести.
Неизвестный
29.10.2009, 11:59
общий
Ashotn:
Вполне стандартный:
POSIX Standard: 7.1-2 General Terminal Interface <termios.h>
Привожу его содержимое:
Код:
$ cat /usr/include/termios.h 
/* Copyright (C) 1991,92,93,94,96,97,98,99, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.

The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */

/*
* POSIX Standard: 7.1-2 General Terminal Interface <termios.h>
*/

#ifndef _TERMIOS_H
#define _TERMIOS_H 1

#include <features.h>
#ifdef __USE_UNIX98
/* We need `pid_t'. */
# include <bits/types.h>
# ifndef __pid_t_defined
typedef __pid_t pid_t;
# define __pid_t_defined
# endif
#endif

__BEGIN_DECLS

/* Get the system-dependent definitions of `struct termios', `tcflag_t',
`cc_t', `speed_t', and all the macros specifying the flag bits. */
#include <bits/termios.h>

#ifdef __USE_BSD
/* Compare a character C to a value VAL from the `c_cc' array in a
`struct termios'. If VAL is _POSIX_VDISABLE, no character can match it. */
# define CCEQ(val, c) ((c) == (val) && (val) != _POSIX_VDISABLE)
#endif

/* Return the output baud rate stored in *TERMIOS_P. */
extern speed_t cfgetospeed (__const struct termios *__termios_p) __THROW;

/* Return the input baud rate stored in *TERMIOS_P. */
extern speed_t cfgetispeed (__const struct termios *__termios_p) __THROW;

/* Set the output baud rate stored in *TERMIOS_P to SPEED. */
extern int cfsetospeed (struct termios *__termios_p, speed_t __speed) __THROW;

/* Set the input baud rate stored in *TERMIOS_P to SPEED. */
extern int cfsetispeed (struct termios *__termios_p, speed_t __speed) __THROW;

#ifdef __USE_BSD
/* Set both the input and output baud rates in *TERMIOS_OP to SPEED. */
extern int cfsetspeed (struct termios *__termios_p, speed_t __speed) __THROW;
#endif


/* Put the state of FD into *TERMIOS_P. */
extern int tcgetattr (int __fd, struct termios *__termios_p) __THROW;

/* Set the state of FD to *TERMIOS_P.
Values for OPTIONAL_ACTIONS (TCSA*) are in <bits/termios.h>. */
extern int tcsetattr (int __fd, int __optional_actions,
__const struct termios *__termios_p) __THROW;


#ifdef __USE_BSD
/* Set *TERMIOS_P to indicate raw mode. */
extern void cfmakeraw (struct termios *__termios_p) __THROW;
#endif

/* Send zero bits on FD. */
extern int tcsendbreak (int __fd, int __duration) __THROW;

/* Wait for pending output to be written on FD.

This function is a cancellation point and therefore not marked with
__THROW. */
extern int tcdrain (int __fd);

/* Flush pending data on FD.
Values for QUEUE_SELECTOR (TC{I,O,IO}FLUSH) are in <bits/termios.h>. */
extern int tcflush (int __fd, int __queue_selector) __THROW;

/* Suspend or restart transmission on FD.
Values for ACTION (TC[IO]{OFF,ON}) are in <bits/termios.h>. */
extern int tcflow (int __fd, int __action) __THROW;


#ifdef __USE_UNIX98
/* Get process group ID for session leader for controlling terminal FD. */
extern __pid_t tcgetsid (int __fd) __THROW;
#endif


#ifdef __USE_BSD
# include <sys/ttydefaults.h>
#endif

__END_DECLS

#endif /* termios.h */
давно
Профессор
230118
3054
29.10.2009, 12:13
общий
vladisslav:
Он не входит в стандарт С, и под Windows обычно не встречается. Только под Unix и клоны.
Неизвестный
29.10.2009, 12:53
общий
Вариант с поддержкой винды (функциональность пока та же)
Код:
/*
This is free software;
you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <conio.h>
#else
#include <termios.h>
#endif
#include <time.h>


#define MAX_WORD_LEN 1024

char * dig2char[10];
char char2dig[256];

void fill_en()
{
dig2char[0]=" 0";
dig2char[1]=".,?!'"1()@/:-";
dig2char[2]="abc2";
dig2char[3]="def3";
dig2char[4]="ghi4";
dig2char[5]="jkl5";
dig2char[6]="mno6";
dig2char[7]="pqrs7";
dig2char[8]="tuv8";
dig2char[9]="wxyz9";
int k;
for(k=0;k<256;k++)
{
char2dig[k]=-1;
};
int t,l;
for(k=0;k<10;k++)
{
l=strlen(dig2char[k]);
for(t=0;t<l;t++)
{
char2dig[dig2char[k][t]]=k;
};
};
};


struct dict_word
{
struct dict_word * next;
char * word;
};

struct dict_node
{
int word_count;
struct dict_word * words;
struct dict_node * next[10];
};

add_to_dict(struct dict_node ** dict,char *str)
{
char * pc=str;
int ln=strlen(str);
char * pe=str+ln;
struct dict_node *pd;
if(ln>0 && *dict == NULL)
{
*dict = calloc(1,sizeof(struct dict_node));
};
pd=*dict;
while(pc<pe)
{
if(pd->next[char2dig[*pc]] == NULL)
pd->next[char2dig[*pc]]=calloc(1,sizeof(struct dict_node));
pd=pd->next[char2dig[*pc]];
pc++;
};
struct dict_word * new_word;
if(pd->words==NULL)
new_word=pd->words=calloc(1,sizeof(struct dict_word));
else{
new_word=pd->words;
while(new_word->next != NULL)
if(strcmp(new_word->word,str)==0)return;
else new_word=new_word->next;
new_word->next=calloc(1,sizeof(struct dict_word));
new_word=new_word->next;
};
new_word->word=calloc(1,ln+1);
strcpy(new_word->word,str);
pd->word_count++;
};


void save_dictionary_fd(struct dict_node * dict,FILE * fd)
{
if(dict==NULL)return;
struct dict_word * word=dict->words;
while(word != NULL)
{
fprintf(fd,"%s\n",word->word);
word=word->next;
};
int k;
for(k=0;k<10;k++)save_dictionary_fd(dict->next[k],fd);
};

int save_dictionary(struct dict_node * dict,char *file_name)
{
FILE * fd=fopen(file_name,"w");
if(fd==NULL)return -1;
save_dictionary_fd(dict,fd);
fclose(fd);
return 0;
};

struct dict_node * load_dictionary(char *file_name)
{
struct dict_node * tmp=NULL;
char buffer[MAX_WORD_LEN];
FILE * fd=fopen(file_name,"r");
if(fd==NULL)return NULL;

while(fscanf(fd,"%s",&buffer)==1)
{
add_to_dict(& tmp,&buffer[0]);
memset(&buffer,0,sizeof(buffer));
};
fclose(fd);
return tmp;
};

struct dict_node * find_dict_node(struct dict_node * dict,char * seq)
{
struct dict_node *pd=dict;
if(pd==NULL)return NULL;
char *pc=seq;
char *pe=seq+strlen(seq);
while(pc<pe && pd != NULL)
{
pd=pd->next[*pc -'0'];
pc++;
};
return pd;
};

struct dict_word * any_word(struct dict_node * dict)
{
struct dict_node *pd=dict;
if(pd==NULL)return NULL;
if(pd->words != NULL)return pd->words;
int k;
struct dict_word *tmp=NULL;
for(k=0;k<10;k++)
if(pd->next[k]!=NULL)
if((tmp=any_word(pd->next[k])) != NULL)return tmp;
return NULL;

};

struct dict_word * find_part_word(struct dict_node * dict,char * seq)
{
struct dict_node *pd=dict;
if(pd==NULL)return NULL;
char *pc=seq;
char *pe=seq+strlen(seq);
while(pc<pe && pd != NULL)
{
pd=pd->next[*pc -'0'];
pc++;
};
if(pd==NULL)return NULL;
return pd->words;
};

void cleanline(struct dict_word *ls,char*add)
{
int len=0;
struct dict_word *lp=ls;
while(lp != NULL)
{
len+=strlen(lp->word);
lp=lp->next;
};
if(len<12)len=12;
len+=strlen(add);
char * buf=calloc(1,len+1);
memset(buf,32,len);
fprintf(stderr,"\r%s",buf);
free(buf);
};

summary()
{
fprintf(stderr,"T9 like input demo.\n");
fprintf(stderr,"\n");
fprintf(stderr,"2-9 - input letters using dictionary.\n");
fprintf(stderr,"1 - input symbols/submit word.\n");
fprintf(stderr,"0 - input space/submit word.\n");
fprintf(stderr,"* - search dictionary for entered sequence of digits.\n");
fprintf(stderr,". - delete last char (does not work for submitted words/spaces/symbols for now.\n");
fprintf(stderr,"\n");
fprintf(stderr,"If sequence has no valid dictionary match input mode will switch to cycle-through-letter-with-delay.\n");
fprintf(stderr,"This will be indicated with "by letters" prompt.\n");
fprintf(stderr,"0-9 - input letters/digits/symbols.\n");
fprintf(stderr,"* - submit and store new word in dictionary/return if empty.\n");
fprintf(stderr,". - delete last char.\n");
fprintf(stderr,"Delay is around 1-2 seconds. Then the same digit will advance to next letter.\n");
fprintf(stderr,"\n");
fprintf(stderr,"Hit Enter to quit.\n");



};


int main()
{
summary();
char buf,indx;
char word[MAX_WORD_LEN];
struct dict_word * word_list=NULL;
struct dict_word * word_last=NULL;
char *current=&word[0];
char t9buffer[MAX_WORD_LEN];
char *pt9=&t9buffer[0];
char *dict_file="dict";
int k;
for(k=0;k<sizeof(word);k++)word[k]=0;
for(k=0;k<sizeof(word);k++)t9buffer[k]=0;
fill_en();
struct dict_node * dict=load_dictionary(dict_file);
fprintf(stderr,"\n");
#ifndef WIN32
/*set up terminal*/

struct termios term,old;
tcgetattr(fileno(stdin),&term);
tcgetattr(fileno(stdin),&old);

term.c_lflag &= ~ICANON;
term.c_lflag &= ~ECHO;
tcsetattr(fileno(stdin),0,&term);
#endif
/*timing*/
time_t prev,now,in_delay;
prev=time(NULL);
now=prev;

struct dict_word * found_word=NULL;
struct dict_node *dn=NULL;
int started=0;
int mode=1;
int symbols=0;
while(1)
{
//buf=fgetc(stdin);read(stdin,&buf,1);
#ifdef WIN32
buf=getch();
#else
buf=getchar();
#endif
now=time(NULL);
in_delay=now-prev;
if(!started)in_delay=0;
prev=now;

if(mode==0 || mode==2)//raw
{
started=1;
if(buf>='0' && buf<='9')
{

indx=buf-'0';
if(in_delay>=2)current++;
if(char2dig[*current]!=indx && *current!=0)current++;
if(*current==0)
*current=dig2char[indx][0];
else
{
int k,l;
l=strlen(dig2char[indx]);
for(k=0;k<l;k++)
{
if(dig2char[indx][k]==*current && k+1<l)
{
*current=dig2char[indx][k+1];
break;
};
if(dig2char[indx][k]==*current && k+1==l)
{
*current=dig2char[indx][0];
break;
};
}
};
if(mode==2 && indx==0) *current = '0';
if(mode==2 && indx==1) *current = '1';
};
if(buf==127 || buf==8 || buf=='.')
{
if(*current != 0)
{
*current=0;
if(current > &word[0])
{
current--;
prev-=2;
}else started=0;
};
fprintf(stderr,"\033[1D ");
//fprintf(stderr,"\r ");
};
if(mode==2 && buf=='*')
{
/*finish editing*/
if(strlen(word)>0)
{
if(word_list==NULL)
{
word_list=calloc(1,sizeof(struct dict_word));
word_last=word_list;
}else{
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
};
word_last->word=calloc(1,strlen(word)+1);
strcpy(word_last->word,&word[0]);
add_to_dict(&dict,word_last->word);
save_dictionary(dict,dict_file);
};
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
current=&word[0];
mode=1;
buf=0;
};
};

if(mode==1)//dict
{
started=0;
int changed=0;
if(buf=='0')
{
//finish word if not possible or switch to 2
if(symbols)
{
if(word_list==NULL)
{
word_list=calloc(1,sizeof(struct dict_word));
word_last=word_list;
}else{
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
};
word_last->word=calloc(1,2);
strcpy(word_last->word,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
symbols=0;
}else{
if(dn == NULL)
{
if(strlen(t9buffer)>0)
{
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
current=&word[0];
mode=2;
};
}else{
if(word_list==NULL)
{
word_list=calloc(1,sizeof(struct dict_word));
word_last=word_list;
}else{
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
};

if(dn->words != NULL)
{
word_last->word=found_word->word;
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
}else{
//submit partial word, add to dict
word_last->word=calloc(1,strlen(t9buffer)+1);
strcpy(word_last->word,&word[0]);
add_to_dict(&dict,word_last->word);
save_dictionary(dict,dict_file);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
};
};
};
if(mode==1)
{
//add space
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
word_last->word=" ";
};
};
if(buf=='1')
{
if(symbols)
{
int k,l;
l=strlen(dig2char[1]);
for(k=0;k<l;k++)
{
if(dig2char[1][k]==*current && k+1<l)
{
*current=dig2char[1][k+1];
if(*current=='1')*current=dig2char[1][k+2];
break;
};
if(dig2char[1][k]==*current && k+1==l)
{
*current=dig2char[1][0];
break;
};
};
changed=1;
}else{
symbols=1;
if(dn == NULL)
{
if(strlen(t9buffer)>0)
{
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
current=&word[0];
mode=2;
};
}else{
if(word_list==NULL)
{
word_list=calloc(1,sizeof(struct dict_word));
word_last=word_list;
}else{
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
};
if(dn->words != NULL)
{
word_last->word=found_word->word;
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
}else{
//submit partial word, add to dict
word_last->word=calloc(1,strlen(t9buffer)+1);
strcpy(word_last->word,&word[0]);
add_to_dict(&dict,word_last->word);
save_dictionary(dict,dict_file);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
};
};
if(mode==1)
{
word[0]=dig2char[1][0];
};
};
};
if(buf>='2' && buf<='9')
{
if(symbols)
{
if(word_list==NULL)
{
word_list=calloc(1,sizeof(struct dict_word));
word_last=word_list;
}else{
word_last->next=calloc(1,sizeof(struct dict_word));
word_last=word_last->next;
};
word_last->word=calloc(1,2);
strcpy(word_last->word,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
symbols=0;
};
*pt9=buf;
pt9++;
changed=1;
};
if(buf=='*' && !symbols)
{
if(found_word!=NULL)found_word=found_word->next;
if(found_word==NULL)
{
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
current=&word[0];
mode=2;
};
};
if(buf==127 || buf==8 || buf=='.')
{
if(pt9 > &t9buffer[0])pt9--;
*pt9=0;
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
fprintf(stderr,"%c ",127);
changed=1;
symbols=0;
};
if(changed)
{
changed=0;
dn=find_dict_node(dict,&t9buffer[0]);
if(dn==NULL)
{
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
found_word=NULL;
dn=NULL;
pt9=&t9buffer[0];
current=&word[0];
mode=2;
}else{
if(dn->words==NULL)
{
found_word=any_word(dn);
}else{
found_word=dn->words;
};
};
if(found_word==NULL)
{
cleanline(word_list,&word[0]);
for(k=0;k<MAX_WORD_LEN;k++)word[k]=0;
for(k=0;k<MAX_WORD_LEN;k++)t9buffer[k]=0;
pt9=&t9buffer[0];
current=&word[0];
mode=2;
};
};
if(found_word != NULL)
{
strncpy(&word[0],found_word->word,strlen(&t9buffer[0]));
};
};

if(buf==10)
{
#ifndef WIN32
tcsetattr(fileno(stdin),0,&old);
#endif
fprintf(stderr,"\n");
exit(0);
};
fprintf(stderr,"\r");
if(mode==2)fprintf(stderr,"by letters :");
else
if(word_list != NULL)
{
struct dict_word * tmp=word_list;
while(tmp != NULL)
{
fprintf(stderr,"%s",tmp->word);
tmp=tmp->next;
};
};
fprintf(stderr,"%s",&word);
};



return 0;
};





Не уверен в том, что виндовый терминал адекватно воспримет ANSI-последовательности (под DOS когда-то давно в детстве приходилось грузить ANSI.SYS)
Форма ответа