Ir ao conteúdo

Posts recomendados

Postado
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/* Constants */
#define T_MORSE 8
#define Q_LETTERS 26
#define Q_NUMBERS 10
#define Q_MORSE (Q_LETTERS+Q_NUMBERS)
#define MAX_STRING_SIZE 50



typedef struct{          /* precisa de uma posição p/ o finalizador de string \0                */
    char letters[5];     /* armazena as letras , pegas como string , mas usa apenas a 1ª letra */
    char lettersMorse[T_MORSE];//* armazena os respectivos simbolos morse das letras                 */
}alphabet;
alphabet l[Q_MORSE];

char process(const char *line) {
    int j, i;
    for (i = 0; line[i]; ++i) {
        for ( j = 0; j < 37; ++j ){      //vector para as letras e numeros em morse
         if (line[i] == l[j].letters[0]){
          printf("%s", l[j].lettersMorse);
          printf("   ");}
        }
    }
}

int main(){
    int cont=0,j;
    FILE *arch;
    arch = fopen("morse.txt","r");
    if( arch == NULL ){
        printf("ERROR");
        return 0;
    }
    else{
        while(fscanf(arch,"%s%s",l[cont].letters,l[cont].lettersMorse) != EOF){
            l[cont].letters[1] = '\0';                            /* elimina caracteres indesejados           */
            for(j=0; j<strlen(l[cont].lettersMorse); j++){
                if(l[cont].lettersMorse[j] == '*'){               /* se encontra um asterisco               */
                   l[cont].lettersMorse[j] = '\0';                /* elimina o asterisco                   */
                   break;
                }
            }

            cont++;                                             /* aponta p/ próxima posição do Vetor      */

        }
    }
    fclose(arch);

    FILE *fp;
    char line[MAX_STRING_SIZE];
    fp = fopen("original1.txt", "r");
    if (arch==NULL){
    printf("ERROR");}
    while (fscanf(fp,"%s",line) != EOF) {
    process(line);
    }
    fclose(fp);

    return 0;
}

Oi, gente! Depois de que umas pessoas aqui me ajudassem com a tarefa de armazenar o alfabeto latino e seu respectivo codigo morse em um estrutura, resolvi fazer um programa para converter em morse um arquivo.txt externo. O problema é que:

meu input (original1.txt) é assim:

2 mais 3 sao 5
estamos em 2019
meu nome eh luis

e meu output são só os numeros em morse. Não converte as letras

Se alguém puder me dar uma luz, ficaria agradecido!

original1.txt

  • Curtir 1
Postado

@KXSY  eu fiz as mudanças baseado no q você escreveu, e agora converte o texto todo, mas os números de maneira errada. Tipo, se é 0 converte como A (em morse), se é 1 como B, 2 como C, etc...

  • Curtir 1
Postado

Esse caminho é um pouco complicado, sem necessidade. Vou acrescentar uns palpites e espero que ajude em algo

 

Escrevi também um programa de exemplo que também toca o texto em Morse, no Windows, em C. Está abaixo. Ouvir o código tem tudo a ver e achei divertido.

 

Veja esse trecho de seu programa por exemplo

else
{
        while(fscanf(arch,"%s%s",l[cont].letters,l[cont].lettersMorse) != EOF){
            l[cont].letters[1] = '\0';                            /* elimina caracteres indesejados           */
            for(j=0; j<strlen(l[cont].lettersMorse); j++){
                if(l[cont].lettersMorse[j] == '*'){               /* se encontra um asterisco               */
                   l[cont].lettersMorse[j] = '\0';                /* elimina o asterisco                   */
                   break;
                }
            }

Talvez esteja vendo a coisa do jeito errado e nadando contra a maré... Esse asterisco é uma salvação e não um peso. É o que se chama de "sentinela" e marca o final do registro...

 

Isso porque acho que sabe que scanf() avança furiosamente sobre espaços em branco, tabs e caracteres de fim de linha, dependendo dos parâmetros. Postei uma explicação lá no outro tópico sobre isso , não sei certo porque tem dois tópicos no mesmo tem. Em https://www.clubedohardware.com.br/forums/topic/1417896-armazenar-letras-de-um-arquivo-em-uma-estrutura/?tab=comments#comment-7664829

 

 

Vou explicar aqui para quem pode não ter lido no outro tópico...

 

Seu arquivo é assim

A .-* 
B -...* 
C -.-.* 
D -..* 

Então essa "máscara" para scanf() 

    const char* mascara = "%c%[^*]%c ";

lê seu arquivo em UMA ÚNICA LINHA de código, graças ao "sentinela". E coloca a letra no char valor, o equivalente em Morse na string codigo, e o asterisco em... asterisco.

 

Esse trecho abaixo abre seu arquivo, lê todos os códigos e mostra na tela o valor em decimal da letra, a letra, o equivalente em Morse e o comprimento da cadeia em Morse. Compare.

{
    const char* mascara = "%c%[^*]%c ";
    char    valor, codigo[80], asterisco; // o obvio
    int        n; // o total de valores lidos por scanf()
    FILE* tabela;
    tabela = fopen(arquivo, "r");
    if (tabela == NULL)    exit(-1);
    while (1)
    {    n = fscanf(tabela, mascara, &valor, codigo, &asterisco);
        if (n != 3) break;
        printf("\t%03d %c\t[%s]\t(%d)\n", valor, valor, codigo, strlen(codigo));
    }
    fclose(tabela);
    return;
};

  E mostra       

        048 0   [-----] (5)
        049 1   [.----] (5)
        050 2   [..---] (5)
        051 3   [...--] (5)
        052 4   [....-] (5)
        053 5   [.....] (5)
        054 6   [-....] (5)
        055 7   [--...] (5)
        056 8   [---..] (5)
        057 9   [----.] (5)
        065 A   [.-]    (2)
        066 B   [-...]  (4)
        067 C   [-.-.]  (4)
        068 D   [-..]   (3)
        069 E   [.]     (1)
        070 F   [..-.]  (4)
        071 G   [--.]   (3)
        072 H   [....]  (4)
        073 I   [..]    (2)
        074 J   [.---]  (4)
        075 K   [-.-]   (3)
        076 L   [.-..]  (4)
        077 M   [--]    (2)
        078 N   [-.]    (2)
        079 O   [---]   (3)
        080 P   [.--.]  (4)
        081 Q   [--.-]  (4)
        082 R   [.-.]   (3)
        083 S   [...]   (3)
        084 T   [-]     (1)
        085 U   [..-]   (3)
        086 V   [...-]  (4)
        087 W   [.--]   (3)
        088 X   [-..-]  (4)
        089 Y   [-.--]  (4)
        090 Z   [--..]  (4)


A única linha

 

n = fscanf(tabela, mascara, &valor, codigo, &asterisco);

Equivalente a

n = fscanf(tabela, "%c%[^*]%c ", &valor, codigo, &asterisco);

 

Onde 

 

tabela é o arquivo, mascara é o que está acima, valor é a letra. codigo é a string arrumadinha pra você usar, asterisco é o próprio sentinela pra você descartar porque ele já cumpriu a função. E se espera que scanf() retorne 3, claro: a letra já no char, a string já no char* e o asterisco

 

Porque funciona?


A máscara 

     const char* mascara = "%c%[^*]%c ";

significa

  •  %c um único caracter, que vai ser a letra ou o digito 
  • %[^*] um número qualquer de caracteres EXCETO um asterisco. ^ significa exceto os próximos dentro de [ ]
  • %c um único caracter que deve ser o asterisco, claro
  • o espaco em branco antes do " final indica que vai consumir tudo que tiver até o fim da linha e o próprio "\n" do fim da linha 

assim cada chamada a scanf() consome uma linha do arquivo como você precisa, deixando o processo por conta de scanf() que foi escrita para isso --- SCAN Formatted data --- e deixando os valores certinhos em uma letra e uma string por exemplo


EXEMPLO QUE TOCA O SOM CORRESPONDENTE AO VALOR EM MORSE 
 

Escrevi  um exemplo para Windows em C que lê um arquivo e mostra na tela o equivalente em código morse usando essa função

void    morse(char* texto, Codigo_Morse* cod); 

Ou mostra o equivalente em Morse de uma string usando essa função

void    morse_frase(char* frase, Codigo_Morse* cod);

Onde texto é o nome do arquivo e frase é a frase a ser "tocada"

 

E também toca o som para você ouvir. Escrevi de um modo que eu imagino bem simples e o programa completo está aqui para ver ou aqui para download

 

Para compilar SEM som apenas comente a segunda linha do arquivo, o #undef
 

#define        __COM_SOM__ 1        
//#undef       __COM_SOM__        // comente essa linha para ouvir o som em Morse

 

O SOM
 

#define        _dot_          (100)    // duracao em ms
#define        _freq_          500    // frequencia do som 500mhz

 

O código Morse usa um tom constante e uma duração. São os parâmetros aí: _dot_ está definido para 100ms, um pouco alto para produção  ---historicamente falando --- mas acho já rápido para quem não tem o ouvido treinado :) como eu não tenho. 60ms era considerado um tempo normal.


E _freq_ é a frequência do som e usei 500Mhz, um tom normal.


voce pode ir mudando esses valores ou apenas cortar o som.

 

A saída na tela

Usando [Clube do Hardware] como parametro

-.-. C .-.. l ..- u -... b . e     -.. d --- o     .... H .- a .-. r -.. d .-- w .- a .-. r . e

Usando arquivo do autor do topico @Luis Vilo como parametro

..--- 2     -- m .- a .. i ... s     ...-- 3     ... s .- a --- o     ..... 5
. e ... s - t .- a -- m --- o ... s     . e -- m     ..--- 2 ----- 0 .---- 1 ----. 9
-- m . e ..- u     -. n --- o -- m . e     . e .... h     .-.. l ..- u .. i ... s


Fim :)

O programa principal que mostra isso é bem simples:

    inicia_tabela(&codigo); // aloca estrutura
    fase2(arquivo_morse, &codigo); // carrega a tabela a partir do arquivo

    char* teste = "Clube do Hardware";
    printf("\n\nUsando [%s] como parametro\n\n", teste);
    morse_frase(teste, &codigo);

    printf("\n\nUsando arquivo do autor do topico @Luis Vilo como parametro\n\n");
    morse("original1.txt", &codigo); // codifica o arquivo
    printf("\n\nFim :)\n\n");

    apaga_tabela(&codigo); // apaga estrutura
    return 0;

Bem como a estrutura de dados que usei

struct morse
{
    char* valor[127];
};
typedef struct morse        Codigo_Morse;

Optei por não usar offsets (deslocamentos) para letras ou números afinal é muito pequeno e assim você pode usar tabelas Morse com menos ou mais valores, por exemplo ou para testar. E o código fica muito mais simples. Veja o programa fonte.

 

Se tiver alguma pergunta... escreva


Espero que ajude a ilustrar o caso do Morse e o de scanf(). Notei que é difícil ver exemplos precisos nos livros e os instrutores parecem não explicar a razão por trás de scanf()

 

:D 

  • Curtir 1
Postado

@arfneto , obrigado pela explicação. O asterisco serve como sentinela mesmo, meu professor me explicou. Agora se não for muito abusar, você (ou outra pessoa) poderia olhar esse código que eu fiz e me ajudar, por favor. Tudo isso é um projeto de escola e eu tô tendo um pouco de dificuldade. Eu tenho de codificar um arquivo e decodificar esse arquivo. A parte de codificar eu já fiz, mas a de decodificar não tá dando muito certo. O problema é que eu Não posso usar funçoes como strcmp, sizeof, memcmp,etc.. para comparar as letras em morse(string), tenho de criar minha própria função e tô me embolando um pouco com isso. Além disso cada letra é separada por tres espaços e cada palavra por cinco (como no arquivo que anexei abaixo).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/* Constantes */
#define T_MORSE 8
#define Q_LETRAS 26
#define Q_NUMEROS 10
#define Q_MORSE (Q_LETRAS+Q_NUMEROS)
#define MAX_STRING_SIZE 100


typedef struct{
    char letras[5]; /* armazena a letra. A recebe como uma string , mas só usa a primeira letra */
    char letrasMorse[T_MORSE];/* armazena os respectivos simbolos morse */
}alfabeto;
alfabeto l[Q_MORSE];

void codifica(const char *linha) {
    int j=0, i=0, p=0;
    char letra[6];
    FILE *fp;
    fp = fopen("mmm.txt", "w");
    while(i<strlen(linha)-1){ //lee a a frase inteira
        while (linha[i] == ' '){
          i++;
        }
        while((linha[i]) !=' '){
            letra[p]= linha[i]; //coloca o caracter de linha na posição i em letra na posição p
            scanf("%c", letra[p]);
            i++;
            p++;
        }while ((letra!=l[j].letrasMorse)&& (j<Q_MORSE)){
            j++;} //aponta para a proxiam letra ou numero
        for(p=0; letra[p]==l[j].letrasMorse[p] && letra[p]=='\0'; p++); // compara strings
        if (letra == l[j].letrasMorse){
              printf("%c", l[j].letras[0]);
        }
        j=0;
    }
}

int main(){
    int cont=0,j;
    FILE *arch;
    arch = fopen("morse.txt","r");
    if( arch == NULL ){
        printf("ERROR");
        return 0;
    }
    else{
        while(fscanf(arch,"%s%s",l[cont].letras,l[cont].letrasMorse) != EOF){
            l[cont].letras[1] = '\0'; /* elimina caracteres indesejados   */
            for(j=0; l[cont].letrasMorse[j]; j++){
                if(l[cont].letrasMorse[j] == '*'){ /* se encontra un asterisco   */
                   l[cont].letrasMorse[j] = '\0';  /* elimina o asterisco */
                   break;
                }
            }
            cont++;  /* aponta para a proxima posiçao do vetor      */
        }
    }
    fclose(arch);

    FILE *fp;
    char linha[MAX_STRING_SIZE];
    fp = fopen("help.txt", "r");
    if (arch==NULL){
    printf("ERROR");}
    while (fgets(linha,MAX_STRING_SIZE,fp) != NULL ) {
    codifica(linha);
    }
    fclose(fp);

    return 0;
}

 

codifica.txt

Postado

Olá!

 

Ouviu o código em Morse com o programa que postei? :D achei bem legal ouvir Morse. E tem aquela função que toca qualquer mensagem,

 

Claro que podemos olhar seu programa. Você poderia postar um novo tópico com ele e o enunciado e eventuais arquivos de teste por favor? Ajuda muito a gente

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...