===
先上效果图:
众所周知,我最近迷上了摩斯电码,想着拿树莓派做个电报机(或类似电报机的东西),于是我就开始提前做准备。写这个转换器的原因是为了等我的蜂鸣器买回来后,可以在树莓派上直接把英语转换成摩斯电码并发出蜂鸣。
于是今天中午我就花了 2 个小时写了个摩斯电码转换器。(主要是解决 git 无法同步,结果最后还是没成功)
思路
思路是这样的:
1. 利用一个链表储存需要转换的字符
2. 把英语字符统一转换为大写
3. 转换为数组中对应的摩斯密码
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define timbre 900 /*timbre 意思是音色*/
#define b_short 200 /* '.' 的发音时长*/
#define b_long 600 /* '-' 的发音时长*/
/*摩尔斯电码对应码表*/
char morse[][5] = {".- "/*A*/, "-... "/*B*/, "-.-. "/*C*/, "-.. "/*D*/, ". "/*E*/,
"..-. "/*F*/, "--. "/*G*/, ".... "/*H*/, ".. "/*I*/, ".--- "/*J*/,
"-.- "/*K*/, ".-.. "/*L*/, "-- "/*M*/, "-. "/*N*/, "--- "/*O*/,
".--. "/*P*/, "--.- "/*Q*/, ".-. "/*R*/, "... "/*S*/, "- "/*T*/,
"..- "/*U*/, "...- "/*V*/, ".-- "/*W*/, "-..- "/*X*/, "-.-- "/*Y*/,
"--.. "/*Z*/};
typedef struct node
{
char data;
struct node *next;
}NODE;
char tmorse(char type, char *code);
NODE* makenode();
void printnode(NODE *NODEhead);
void freenode(NODE *NODEhead);
void printmorse(NODE *NODEhead);
void clearcode(NODE *NODEhead);
NODE* trans_morse(NODE *NODEhead);
void makesound(NODE *NODEhead);
int main()
{
NODE *head;
NODE *NODEmorse;
head = makenode();
printf("\nThe string after change are:\n");
clearcode(head);
printnode(head);
printf("\n"); /*用于打印空行*/
printf("\nThe morse code are :\n");
NODEmorse = trans_morse(head);
printnode(NODEmorse);
//printmorse(head);
printf("\n");
makesound(NODEmorse);
freenode(head);
freenode(NODEmorse);
return 0;
}
char tmorse(char type, char *code)
{
if(type=='e' || type=='E')
{
printf("功能暂时未完成");
}
else if(type=='m' || type=='M')
{
}
else printf("%c is not right, please type 'e' or 'm'!",type);
}
/*把小写转换为大写*/
void clearcode(NODE *NODEhead)
{
NODE *t;
t = NODEhead;
while(t!=NULL)
{
if(t->data >= 'a' && t->data <= 'z')
t->data = t->data - ('a'-'A');
t = t->next;
}
}
/*打印摩斯电码*/
void printmorse(NODE *NODEhead)
{
NODE *t;
t = NODEhead;
while(t!=NULL)
{
if(t->data >= 'A' && t->data <= 'Z') /*只转换英文*/
printf("%s",morse[(t->data)-'A']); /*转换为对应位置的摩尔斯密码*/
else
printf("%c",t->data);
t = t->next;
}
}
/*创建链表*/
NODE* makenode()
{
/*创建链表*//*尾插法*/
NODE *head;
head = NULL;
NODE *p, *q;
char a;
while(1)
{
scanf("%c",&a);
if(a == '\n') break; /*遇到回车结束读取,跳出循环*/
p = (NODE *)malloc(sizeof(NODE));
p->data = a;
p->next = NULL;
if(head == NULL)
head = p; /*如果这是第一个创建的节点,将头指针指向这个节点*/
else
q->next = p;/*如果不是,将上一指针指向当前节点*/
q = p;
}
return head; /*返回链表首地址指针*/
}
/*打印链表*/
void printnode(NODE *NODEhead)
{
NODE *t;
t = NODEhead;
//clearcode(t); /*把小写统一转换为大写*/
while(t!=NULL)
{
printf("%c",t->data);
t = t->next;
}
}
/*释放链表*/
void freenode(NODE *NODEhead)
{
NODE *t, *s;
t = NODEhead;
while(t!=NULL)
{
s = t; /*保存当前位置*/
t = t->next;
free(s); /*释放动态申请内存*/
}
}
NODE* trans_morse(NODE *NODEhead)
{
NODE *t, *p, *q;
NODE *head;
t = NODEhead;
head = NULL;
int i = 0, j = 0;
while(t!=NULL)
{
if(t->data >= 'A' && t->data <= 'Z')
{
for(i=0; morse[t->data - 'A'][i]!=' '; i++) //不该这样的,应该判断是否为'\0',
{ //可为什么如果判断是否为'\0'的话
p = (NODE *)malloc(sizeof(NODE)); //读取'h'的时候就会把'i'的一起读取了
p->data = morse[t->data-'A'][i]; // 变成了'.... ..'
p->next = NULL;
if(head == NULL)
head = p;
else
q->next = p;
q = p;
}
p = (NODE *)malloc(sizeof(NODE)); //下面这些都是为了解决不能读'\0'
p->data = morse[t->data-'A'][i]; //这个问题的,用于补一个空格回去
p->next = NULL; //不然每个字母中间没有空格
if(head == NULL) //
head = p; //
else // 渣渣代码
q->next = p; //
q = p; // (╯‵□′)╯︵┻━┻
}
else
{
p = (NODE *)malloc(sizeof(NODE));
p->data = t->data;
p->next = NULL;
if(head == NULL)
head = p;
else
q->next = p;
q = p;
}
t = t->next;
}
return head;
}
void makesound(NODE *NODEhead)
{
NODE *t;
t = NODEhead;
while(t!=NULL)
{
if(t->data == '.')
{
Beep(timbre,b_short);
printf("%c",t->data);
}
else if(t->data == '-')
{
Beep(timbre,b_long);
printf("%c",t->data);
}
else if(t->data == ' ' /*&& t->next->data != ' '*/) // 这里暂时先注释掉,运行的话“return valve 3221225477”,只能先自己控制空格数量了
{
Sleep(b_long);
printf("%c",t->data);
}
t = t->next;
}
}
后记
摩斯码转英文部分还未完成,以后可能更新
/2018年5月11日 @ 13:22 发布代码
/2018年5月22日 @ 12:39 更新代码(增加 trans_morse() 和 makesound() )