Problema em C

LaNgSuYaR

Power Member
boas!! tenho andado a desenvolver um trbalho em C pr as aulas, e estou aki com um dilema...

o programa é uma aplicação de desenho em C, em que o utilizador insere um comando e uma coordenada, e a maquina produz o efeito desejado!

so que é o seguinte, existem diversos comandos (pontos, linhas, rectangulos) e para cada um vai ser criada a respectiva função (void pontos(linha, coluna) p.ex...
o que gostaria de saber era se é possivel o programa identificar os comandos que o utilizador escreve e recorrer à função adequada...isto sem usar o switch, pk ao usa-lo, se em vez do utilizador escrever "Point" escrever "point" já não iria funcionar!!!

ajuda agradecida!!!
cumps!
 
Penso que isto resolve o teu problema:

Código:
char input[16];      //string que recebe o comando
char *input_lower_case;
gets(input);
 
input_lower_case = strlwr(input);
 
puts(input);         //pa verificar se faz bem
 
switch(input)
     case(point): função que queres
     case(...): por aí fora

Assim já podes usar o switch, ou ifs ou whiles...
Cumprimentos
 
Última edição:
entao o que aconselham, fazer um primeiro switch pra "captar" o nome do comando, e um segundo pra verificar se os parametros estao correctos....

ja agora, pra separar uma string pelos espaços cm qual é a melhor maneira a proceder?!?!

tnkx!!!
cumps
 
#include <string>

string ex;

for(int i= 0 ; i< ex.size(); i++)

aux= ex;
if (aux == ' ')
{
string sub = ex.substr(aux1, aux2);
aux1=aux;
}


Não sei se funciona, nem sei se está perto da melhor soluçao, fiz isto mesmo agora, nem testei.

Claro que isto vai estar sempre a trocar o valor do sub. Isto é se funcionar :004:
 
bem, pra comparar a string, aconselharam-me uma função, strcmp() k compara alfabeticamente 2 strings....e definiu-se que o utilizador tem de inserir o comando exacto (p.ex. "Dim" em vez de "dim")....mas ainda não testei....

para separar uma string pelos espaços estou a fazer com o seguinte código:
gets(comando);
n=strlen(comando);
for(i=0;i<=n;i++)
{
if (comando==' ' || i==n)
puts(aux);
else
aux=comando;
}


ainda não acabei nem ele funciona ainda...aki supostamente ele vai guardar os caracteres todos na variavel aux até ao primeiro espaço e depois qnd encontrar o espaço "imprime" a variavel aux, e vai acrescentando (fase de testes!!!! lol) até ao fim da string 'comando'...mas tenho tido alguns problemas ainda....

quando digito "dim" p.ex., aparece-me: "dim\200\200"
enquanto que se escrever uma palavra com 5 letras, "manip" p.ex., aparece-me correctamente!!! e não tou a ver a causa do problema!...

como já referi, ainda está em fase de testes e o resultado final n vai ser este claro, mas gosto de ver os resultados no monitor a cada passo antes de trabalhar cm variaveis e apresentar o resultado final apenas!!!


já agora desculpem tda a minha ignorância, mas tenho-me baseado apenas num livro e em bases de algoritmia, mais nada!!! (é no que dá ser baldas! lool)...

tnkx in advance...
cumps


edit: já consegui resolver o problema... :D
gets(comando);
n=strlen(comando);
for(i=0;i<=n;i++)
{
if (comando==' ' || i==n)
{
for(k=0;k<j;k++)
printf("%c",aux[k]);
j=0;
printf("\n");
}
else
{
aux[j]=comando;
j++;
}
}


já separa palavra a palavra e imprime-a no monitor...agora só falta arranjar maneira de guardar numa variavel de cada vez que encontre um espaço.... hummmm.... :rolleyes:
 
Última edição:
Olha, usa:
char *fgets(char *s, int size, FILE *stream);

em vez do gets, é mais seguro (Ver man gets). Esta função lê até ao '\n' ou até ao limite (size).

Depois, sabes se os argumentos de cada linha são variaveis?
é que se for so algumas variaçoes podes usar a funçao

int sscanf(const char *str, const char *format, ...);

por exemplo:
nritens = sscanf(linha,"%s %d %d",nomefuncao,&x,&y);

e com isso podes ver o nritens que dá 3 se correr td bem, e ficas logo com o nome e os valores do x e y em variaveis.


Depois para veres qual a funçao a usar tens:
int strcasecmp(const char *s1, const char *s2) -- case insensitive version of strcmp().
int strncasecmp(const char *s1, const char *s2, int n) -- case insensitive version of strncmp().
 
Para separar por espaços (ou por qualquer outro delimitador) tens sempre o strtok (deprecated) e o strsep.

man strtok disse:
char *strtok(char *str, const char *delim);

DESCRIPTION
The strtok() function parses a string into a sequence of tokens. On
the first call to strtok() the string to be parsed should be specified
in str. In each subsequent call that should parse the same string, str
should be NULL.

RETURN VALUE
The strtok() and strtok_r() functions return a pointer to the next token, or NULL if there are no more tokens.
man strsep disse:
char *strsep(char **stringp, const char *delim);

DESCRIPTION
If *stringp is NULL, the strsep() function returns NULL and does nothing else. Otherwise, this function finds the first token in the string *stringp, where
tokens are delimited by symbols in the string delim. This token is terminated with a `\0' character (by overwriting the delimiter) and *stringp is updated
to point past the token. In case no delimiter was found, the token is taken to be the entire string *stringp, and *stringp is made NULL.

RETURN VALUE
The strsep() function returns a pointer to the token, that is, it returns the original value of *stringp.
 
kanguru disse:
Olha, usa:

int sscanf(const char *str, const char *format, ...);

por exemplo:
nritens = sscanf(linha,"%s %d %d",nomefuncao,&x,&y);

e com isso podes ver o nritens que dá 3 se correr td bem, e ficas logo com o nome e os valores do x e y em variaveis.



humm yah, talvez funcione...o prob é que certos comandos só têm 2 variaveis (Dim x,y) e outros têm N....(PolyLine x1,y1,x2,y2,x3,y3,x4,y4).

Portanto, se definir "nritens = sscanf(linha,"%s %d %d",nomefuncao,&x,&y);", fico com 3 variaveis disponiveis, mas se definir com 5 ou 6, se forem colocadas menos dá erro certo???



PrOdG: por acaso nao conhecia o strtok ;) e é grande ideia, evita bastante trabalho, mas mesmo assim não estou a ver maneira de as guardar em variaveis....pk n sei quantos valores o utilizador vai inserir.... :S
 
em principio podes ver pelos dados inseridos se são 3 5 ou 6 inseridos e com isso fazes um tratamento diferente. Não garanto que funcione mas é uma ideia :)
 
ja arranjei uma solução....
numa primeira fase filtro so o primeiro comando (dim, line, etc) guardando-o numa variavel e o resto da string é guardado numa variavel auxiliar....

quando o comando for reconhecido (vi-me forçado a usar a estrutura de if's), pego na variavel auxiliar e uso-a de acordo com o comando....ja fiz 2 ou 3 comandos e resultou!!!

hummm gostava de agradecer toda a vossa ajuda e disponibilidade, e....se aparecer mais alguma duvida, posto aki!!!!

cumps!!!
 
humm bem, estou aki com um problema..
uma das funções do trabalho é "line x1,y1,x2,y2"....e esta função é pra fazer linhas ta claro! lol numa matriz[col][lin] mas estou a ter problemas em fazer linhas cujo declive é diferente d 0...ou seja, linhas horizontais e verticais sem problema...

o código que tenho é este:

void line()
{
int x1, x2, y1, y2, m y, x;
m=(y2-y1)/(x2-x1);
x=x1;
for(j=0;j<y2;j++)
{
for(i=0;i<m;i++)
{
printf("j+y1=%d - i+x1=%d\n",(j+y1), (i+x1));
printf("%d -> x\n",x);
printf("y1+j -> %d\n",(y1+j));
matriz[(y1+j)][x]=caracter;
x++;
}
}
mostramatriz();

e ao desenhar linhas obliquas, elas ficam desfiguradas...lol....anyone?

cumps
 
LaNgSuYaR disse:
humm bem, estou aki com um problema..
uma das funções do trabalho é "line x1,y1,x2,y2"....e esta função é pra fazer linhas ta claro! lol numa matriz[col][lin] mas estou a ter problemas em fazer linhas cujo declive é diferente d 0...ou seja, linhas horizontais e verticais sem problema...

o código que tenho é este:



e ao desenhar linhas obliquas, elas ficam desfiguradas...lol....anyone?

cumps

tu quando crias por exemplo um vector de inteiros:
"int vector[DIMx]" crias um vector de uma dimensão, mas ao fazeres:
"int vector[DIMx][DIMy] crias um vector de duas dimensoes, ou seja, uma matriz as linhas da matriz n ficam onde escrevi DIMx ? podes ter-t enganado ai (embora seja possivel trocar).
 
Pa, acho que estás a ter uma abordagem errado ao problema. Pelo código ainda pensei que querias fazer gráficos de barras...

A fórmula da linha é y = m*x + b
assim só precisas de iterar ao longo de x e aplicar a fórmula. Outra nota importante é que m tem que ser do tipo float ou double, caso contrário perdes precisão, bem como todas as contas internas.
m = (y2-y1)/(x2-x1)
b = (y1*x2 - y2*x1)/(x2-x1)
for (x=x1; x<=x2; x++)
y = m * x + b
mat[y][x] = c
 
mas pelo código que disponibilzast, as linhas obliquas nao ficam como deviam ficar...
foi-me dito que teriam de ser em forma de escada (se desenhares uma linha no paint, aparece em escada certo??)e pra obter esse resultado penso que pela formula das linhas (y = m*x + b) nao dá....

por acaso tinha pensado nisso mas ainda n tinha experimentado...mas pra fazer as tais "escadas" a k me refiro tenho d abordar de forma diferente n sera?
 
epa, fizeste-me mesmo experimentar o código.
Código:
#include <stdio.h>
void line(char mat[10][10], int x1, int y1, int x2, int y2)
{
        double m = (double)(y2-y1) / (x2-x1);
        double b = (double) (y1*x2 - y2*x1) / (x2-x1);
        int x;
        for (x=x1; x<=x2; x++) {
                int y = m * x + b;
                mat[y][x] = '*';
        }
}
void p(char mat[10][10])
{
        int x,y;
        for (y=0; y<10; y++) {
                for (x=0;x<10;x++) {
                        char c = mat[y][x];
                        printf("%c ", c ? c : ' ' );
                }
                printf("\n");
        }
}
int main()
{
        char mat[10][10]; /* mat[col][line] */
        memset(mat,0,sizeof(mat));
        line(mat,2,1,9,6);
        p(mat);
}


Resultado
Código:
# ./a.out 
                    
    * *             
        *           
          * *       
              *     
                *   
                  *

Se variares os parametros obtens sempre linhas que vão do ponto x1,y1 ao x2,y2 dentro da maior aproximação possível.
Não entendo bem o que queres dizer com "efeito escado", se é preencher tudo abaixo do asterisco até zero, então é preciso um segundo for, de facto.
 
desculpem lá a noobice, mas nao vai haver problemas ao usar o array como parametro de funcoes auxiliares?
tipo, a ideia que tenho é que ao dar o array como parametro de uma funcao, a funcao usa uma copia do array, e nao o proprio array, e consequentemente as alteração vao à vida assim que a funcao auxiliar terminar. certo ou errado?

tambem ajudei uns colegas a fazer esse trabalho e eles tiveram que implementaram todas as operacao de escrita na matriz dentro da main...

alguem que confirma ou desminta essa necessidade, sff?
 
Back
Topo