Ir ao conteúdo
  • Cadastre-se

C Criar uma função que receba o primeiro caractere registrado na matriz


Yank Marsh

Posts recomendados

Em 04/07/2020 às 07:44, Yank Marsh disse:

A matriz está funcionando,MAS:

1 não gera letras maiusculas.

2 Não conta o numero de cada ocorrencia de caracteres, e não lista eles.

A solução vai ser tirar o gerador de letras

 

Não é uma solução, eu creio. Apenas deixou de fazer algo.

 

E tirar o gerador de letras não vai fazer os itens 1 e 2 funcionarem.

 

Pense assim: Podemos gerar a matriz com qualquer conteúdo, desde que se possa mostrar, coisas que se pode mostrar, tipo letras, números e símbolos. Espaços já não seria uma boa, caracteres como ESC ou TAB também não. ;) já que não daria pra ver. C tem uma rotina, isprint() que retorna 0 se o valor não é "imprimível" e já serviria. 

 

Como gerar a matriz apenas com letras maiúsculas e minúsculas misturadas?
 

Tem um milhão de maneiras de fazer isso. Usando srand() e rand() pode preencher a matriz com o que quiser. Uma solução simples para as letras seria:

  • x = (rand() % 26) vai dar um número entre 0 e 25.
  • então (x + 'a') vai dar um número entre 97 e 125, no popular entre 'a' e 'z' como vê no trecho da tabela abaixo: o código de 'a' é 97 e são 26 letras
  • y = rand() % 2 e vai o que? zero ou um, certo?
  • E veja que um 'A' vale 65, a diferença entre as letras maiúsculas e minúsculas é de 32. E as minúsculas são maiores porque no começo desse código --- ASCII --- os computadores e impressoras só tinham maiúsculas.
  • Então quando vale z = x - (y * 32) ? Uma letra. Como y pode ser 0 ou 1 e x é uma letra minúscula --- porque a gente escreveu assim --- então é claro que vamos ter uma letra, maiúscula ou minúscula 50-50
  • Não estou dizendo que seja uma maneira eficiente ou boa de fazer isso, é bem ingênua e chama rand() duas vezes e tal, mas é bonitinha e esse é um programa para aprender a programar. E assim não desistimos
     

Traduzindo de português para C, um exemplo:

        x = (rand() % 26); // x entre 0 e 25
        x = x + 'a'; // x virou uma letra entre 'a'e 'z'
        y = rand() % 2; // y vale 0 ou 1
        x = x - y * 32; // x agora pode ser maiuscula se y for 1

E um programa usando isso para uma matriz 256, que é um número bacana:

n C P I k S K S T u n s g A K N
T n S a k q m u C j G C v C I Y
A x p Y e D k H F c C M L F n S
f u m W h w B P i v M F p d a b
k k r t Z k V X Y G h q N T Q g
y c y G S J z p n a p H M L R c
e B R n e B q p k c i A J N a T
F D J s w H Q c A i h X U O A n
z A B N V r W s Z e b q A u V k
q c Y x N t F B e Z d k i w w g
x F A l b Q D O n L k e I a A W
f Y X r y e Z C h S k a r i z H
Z I i Z O h N p j A T a i n R P
H V e B m Q M L U i I L H h n y
Q r v M C i H B s L C h W L U X
D m I W t p A l F x p Y u Z H O

O programa é só isso mesmo, em um loop, certo?

#include <stdio.h>
int main()
{
    srand(20200705);
    int x = 0;
    int y = 0;
    int z = 0;
    for (int i = 0; i < 256; i += 1)
    {
        x = (rand() % 26); // x entre 0 e 25
        x = x + 'a'; // x virou uma letra entre 'a'e 'z'
        y = rand() % 2; // y vale 0 ou 1
        x = x - y * 32; // x agora pode ser maiuscula se y for 1
        z = z + 1;
        printf("%c ", x);
        if ((z % 16) == 0) printf("\n");
    };  // for()
    printf("\n");
    return 0;
};
//  fim

Veja a tabela ASCII aqui embaixo e note que entre 33 inclusive e 126 inclusive pode imprimir tudo então também pode usar isso no programa. Entre 33 e 126 são 94 símbolos. Como ficaria no programa? A mesma coisa, só que mais simples:

        x = (rand() % 93); // x entre 0 e 92
        x = x + '!'; // agora fica entre '!' e '~'

basta trocar dentro do loop por isso. veja uma execução

g T $ Y ? u g I j x w J { } n )
B W ! _ B L s 2 L b V e g - o v
R / ` g C \ D h % - w l R b l Y
/ c ' y W Y - ( D % U D 7 D " A
{ | ] 3 - M Z ^ E z 6 ^ Z + { P
a - ( < g o t s N ] p w 4 L / W
a j 9 ] U ; C Q 9 % ; g E H # g
C g # v _ w I x 2 , ^ O M ! + E
o ^ - . : ? t { [ A * 3 @ " $ W
B i e a d } B , < B h n 2 b p %
] 8 ` f P x S + 5 C r h s x L ?
| = Y q ? : C * / N . b ' & ! ^
1 l W P L Z ^ T 9 q F 5 J H O q
b F 7 ? m , Q , 3 8 A u 3 \ z S
\ 0 e S ^ V a k + S [ ` & G c w
+ C O ! 5 = y r A > / 6 ; H - m

 

image.png.fa0cd2edbbbd66ab4998dca616e200bf.png

 

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

@arfneto     boa essa função ,  e ela está gerando os caracteres bem , e tem muitas linhas , essa aqui tem menos linhas   :

for( i=0; i<linha; i++ ){             // contador de linhas
    for( j=0; j<coluna; j++ ){        // contador de colunas
        do{
            mat[i][j] = rand() % 58 + 65;
        }while( mat[i][j] > 90 && mat[i][j] < 97 );
        mat_aux[i][j] = mat[i][j];
        // t eh um caractere que não pode ter na martriz
        if( achou )t++;               // nao pode ser esse caractere
        achou = 0;                    // vai scolher outro caractere
        if( ! i && ! j )t=mat[i][j];  // inicializa a variável t com o primeiro caractere da matriz
        if(mat[i][j] == (char)t)      // t é um caractere que não pode estar na matriz
            achou = 1;
    }
}

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

3 horas atrás, devair1010 disse:

esse visual studio é cheio de detalhes e aqui estou usando o codeblocks e nele não precisa , dessa biblioteca , 


#include <ctype.h>

creio que seja isso  .

 

Não entendo o que quer dizer com isso. Tem algum outro exemplo? Que detalhes seriam esses?

 

Os headers nada tem a ver com Code::Blocks ou o compilador. São apenas isso: declarações de tipos e funções. 

Essa família de funções toupper(), isdigit() isprint()  e tal reside em ctype.h 

 

E você esqueceu o include e ignorou o aviso do compilador. Ou configurou para não mostrar.

 

Entenda que Code::Blocks não é um compilador. Assim como Visual Studio não é. Você pode ou deveria poder usar qualquer compilador com o Code::Blocks. Não com o Visual Studio. 

 

Veja abaixo a lista de compiladores no Code::Blocks. Veja a idade das coisas lá: Borland C++ 5.5, MSCV Toolkit 2003... Mas deve ser possível associar algum compilador mais moderno também. E atualizar a versão de GCC ou manter várias porque muita gente precisa.
 

image.png.2906c7aaebd12adf3a93f04d42dfbc1b.png


Colocando "--version" nas opções de compilador do Code::Blocks você pode ver
 

image.png.a822fcf9fd161c653fabdd7c318be5d3.png

 

Na máquina em que foi compilado então tem essa versão de gcc, que nem é muito antiga. Mas você pode ter várias na máquina e selecionar lá no perfil qual quer usar.

 

Só isso.

 

Veja na mesma tela como seria rodar isso no visual studio, no Code::Blocks e no Linux: 
 

image.thumb.png.6d5d98a6f7060d3d229011ab5dea1ce9.png

 

E a mensagem é a mesma. Você apenas não prestou atenção na saída do compilador. 

 

O programa vai rodar porque stdlib em geral está disponível para o linker e assim acaba funcionando. No Linux ou no Windows, com gcc ou CL

 

No Dev-C++ é bem melhor escrito:
 

image.png.69240b5d51197e80e19f510f1168710b.png

 

Você pode apertar o botão verde e acrescentar o compilador que precisa usar e dar um nome pra ele... E as opções que quer usar para compilar ficam logo ali. Então pode ter várias configurações para o mesmo compilador com nomes diferentes e mudar com um click só...

 

 

 

adicionado 19 minutos depois
3 minutos atrás, devair1010 disse:

boa essa função ,  e ela está gerando os caracteres bem , e tem muitas linhas , essa aqui tem menos linhas

 

Não sei se entendo o que quer dizer. 

 

É para ser legível e traduzir no programa o que foi dito no texto, e assim fica

    for (int i = 0; i < 256; i += 1)
    {
        x = (rand() % 26); // x entre 0 e 25
        x = x + 'a'; // x virou uma letra entre 'a'e 'z'
        y = rand() % 2; // y vale 0 ou 1
        x = x - y * 32; // x agora pode ser maiuscula se y for 1
        z = z + 1;
        printf("%c ", x);
        if ((z % 16) == 0) printf("\n");
    };  // for()
    printf("\n");

Que é o que está lá. E entenda que além disso z é para controlar as quebras de linha na impressão. 

 

Usar 3 loops e todos esses testes aqui
 

for( i=0; i<linha; i++ ){             // contador de linhas
    for( j=0; j<coluna; j++ ){        // contador de colunas
        do{
            mat[i][j] = rand() % 58 + 65;
        }while( mat[i][j] > 90 && mat[i][j] < 97 );
        mat_aux[i][j] = mat[i][j];
        // t eh um caractere que não pode ter na martriz
        if( achou )t++;               // nao pode ser esse caractere
        achou = 0;                    // vai scolher outro caractere
        if( ! i && ! j )t=mat[i][j];  // inicializa a variável t com o primeiro caractere da matriz
        if(mat[i][j] == (char)t)      // t é um caractere que não pode estar na matriz
            achou = 1;
    }
}

E depois excluir os caracteres que são inválidos e tal é uma lógica confusa para um estudante.
 
E de todo modo não é eficiente: são 3 loops e vários if() para acertar os valores.
 

Se quer escrever assim use apenas as 52 letras na chamada a rand(): rand%52. E se for maior que 25 você apenas  subtrai o 32 para usar a maiúscula. Só isso e já funciona.

 

No entanto é melhor seguir o caminho que eu expliquei. Se não precisa ser legível e quer usar poucas linhas escreva assim:

void     arruma_matriz(char* M, int linhas, int colunas)
{
    for (int i = 0; i < linhas * colunas; i += 1)
        *(M + i) = (rand() % 26) + 'a' - (rand() % 2 * 32);
};

 

Que só tem uma linha, um loop, que preenche a matriz com maiúsculas e minúsculas e já funciona para qualquer número de linhas e colunas. Com um único loop e uma única variável local, o índice do loop...

 

 

 

  • Curtir 3
Link para o comentário
Compartilhar em outros sites

7 minutos atrás, devair1010 disse:

ele não mostrou nenhuma notificação e o código está sem aquele include

 

É como te expliquei. Essas funções estão onde eu disse que estão, desde os anos 80. Você deve ter suprimido os warnings apenas. Mas isso não é relevante. O código é gerado a menos que você tenha exigido para não gerar se tiver algum alerta. Tem lugares que exigem isso (empresas e escolas). 

 

Recomendo ler o que eu disse acima sobre essas funções e o trecho de código que escreveu. Tem um exemplo lá e alguns comentários que podem ser úteis

 

 

adicionado 2 minutos depois

Um exemplo de como preencher a matriz, usando a tal função de uma linha

 

Agora 6 matrizes com tamanho e atributos aleatorios
Teste 1 de 6: Matriz [8,3] opcao 0

L b p
y x r
T b O
i g g
z X V
H y v
a q u
m e T

Teste 2 de 6: Matriz [7,7] opcao 1

C v C I Y A x
p Y e D k H F
c C M L F n S
f u m W h w B
P i v M F p d
a b k k r t Z
k V X Y G h q

Teste 3 de 6: Matriz [8,6] opcao 1

t b s g a m
b N Z Q K i
M S n V D j
o E J B e Y
z M s i a o
X J p C H B
N l k W v f
u t A I v d

Teste 4 de 6: Matriz [4,7] opcao 1

n z A B N V r
W s Z e b q A
u V k q c Y x
N t F B e Z d

Teste 5 de 6: Matriz [3,3] opcao 0

q k k
O G v
N M a

Teste 6 de 6: Matriz [10,4] opcao 1

O n L k
e I a A
W f Y X
r y e Z
C h S k
a r i z
H Z I i
Z O h N
p j A T
a i n R

Para esse programa de exemplo

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

void    arruma_matriz(char*, int, int);
int     mostra_matriz(char*, int, int);

int main()
{
    srand(20200705);
    char    matriz[10][10]; // a matriz maior possivel
    int N = 6; // N testes com matrizes aleatorias
    printf("Agora %d matrizes com tamanho e atributos aleatorios\n", N);
    printf("Opcao 1 = so letras, opcao 0 = simbolos entre '!' e '~'\n\n");
    for (int i = 1; i <= N; i += 1)
    {
        int l = rand() % 10 + 1; // linhas
        int c = rand() % 10 + 1; // colunas
        int o = rand() % 2; // opcao
        printf("Teste %d de %d: Matriz [%d,%d] opcao %d\n\n",
            i, N, l, c, o);
        arruma_matriz(&matriz[0][0], l, c); // 0 para usar de ! a ~ 
        mostra_matriz(&matriz[0][0], l, c);
    };  // for()
    return 0;
};


void     arruma_matriz(char* M, int linhas, int colunas)
{
    for (int i = 0; i < linhas * colunas; i += 1)
        *(M + i) = (rand() % 26) + 'a' - (rand() % 2 * 32);
};

int mostra_matriz(char* M, int L, int C)
{
    // mostra na tela a matriz M[L,C]
    int N = L * C; // o tamanho da matriz
    int z = 0;
    char* p = M;
    for (int i = 0; i < N; i += 1)
    {
        z = z + 1;
        printf("%c ", *(p + i));
        if ((z % C) == 0) printf("\n");
    };  // for()
    printf("\n");
    return 0;
};

//  fim

 

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

Você não respondeu nada sobre os exemplos que perguntei em relação ao detalhes do Visual Studio. Eu instalei esses outros na mesma máquina e estou comparando. O Code::Blocks e o Dev-C++ e o Visual Studio e o VS Code e o Eclipse. Fiquei curioso 

adicionado 3 minutos depois
2 minutos atrás, devair1010 disse:

o codeblocks da versão 16.01 , que instalei não foi configurado , apenas cliquei em instalar e ficou assim mesmo

 
Recomendo ir lá nas opções do compilador e marcar --version para ver qual versão de gcc está usando e na opção de warnings marcar -Wall no formulário se usa programas compilados lá para postar no forum. Assim você vai saber o que outros vão ver. E é boa política de todo modo.

 

 

adicionado 6 minutos depois

E se Code::Blocks continua com a opção ***** de assumir o C++ de 98 e o C de 89 como padrão sugiro mudar isso também de imediato usando -std=c99 ou -std=c11 ou -std=c17 e confirmar que isso está indo para o gcc.

 

Não dá pra imaginar que não tenha nada errado em usar C de 1989 ou C++ de 1998 sem perder nada de bom que se tenha criado nesse período de mais de 30 anos...

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

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...