Jump to content

leitura de string do teclado


Heirophant
 Share

Recommended Posts

Heirophant

Boas pessoa. Preciso de uma ajuda..

Preciso de fazer a leitura de uma string a partir do teclado como se fosse um comando, ou seja:

Um scanf ou gets por exemplo do comando soma 1 2 3 .... n

Na leitura da string preciso que o comando soma chame e função somar por ex... e que a funcçao somar faça somas com os numeros que são fornecidos na string.

O problema é que eles são delcarados como sendo partes da string e não sei como passa-los a inteiros. Se fosse um numero certo de parametros era facil mas os parametros têm de poder variar e não sei fazer isso.

Resumidamente o que preciso é que o primeiro parametro (soma neste caso) seja associado a um char[n] ou seja, uma string, e os restantes elementos sejam transformados em inteiros individualmente! int a=1, int b=2... int x=n...

Será que alguem me pode ajudar? ou pelo menos dar umas luzes?

Agradeço desde já

Link to comment
Share on other sites

Boas,

Não sei se o que pretendes é isto, mas podias fazer tipo uma função com os parametros (peço desculpa se tiver alguma coisa errada porque ainda não me dediquei muito as funções em C)

char funcao (char opc[10] float valor,valor2)
    {
    switch(opc)
        {
        case 'soma':
                         valor+valor2;
                         break;
        case 'subtracçao':
                         valor-valor2;
                         break;
        ....................
        }

E no corpo do programa

main()
    {
    menu;
    printf("Introduza a opcao");
    scanf("%s",opc);
    printf("Introduza o primeiro valor");
    scanf("%f",valor);
    printf("Introduza o segundo valor");
    scanf("%f",valor2);
    funcao (opc,valor,valor2)
    }

Espero que esteja perceptivel e que tenha ajudado em qualquer coisa.

Cumps, 

Link to comment
Share on other sites

Heirophant

maiden isso foi +- o que eu fiz! mas eu queria passar todos os parametros todos de uma só vez! Sem scanf's para todos os valor!

unknown apenas penso que será a melhor maneira de o fazer... mas não tem obrigatoriamente de ser assim. Apenas pus isso para se perceber melhor!

Link to comment
Share on other sites

unknown apenas penso que será a melhor maneira de o fazer... mas não tem obrigatoriamente de ser assim. Apenas pus isso para se perceber melhor!

Ok, eu estava a pensar numa maneira diferente da do MaIdEn_DuDe mas ia dar aos mesmos "scanf's" :)

Link to comment
Share on other sites

Heirophant

o objectivo é ter apenas um scanf ou gets que receba um comando completo e que de como resultado uma string com o nome do comando (por exmeplo: soma) e transforme todos os outros parametros em inteiros!

Link to comment
Share on other sites

Pois isso é que é mas dificil pa um noob como eu  ?

Espero que consigas arranjar uma maneira de fazer isso.

Se me lembrar de alguma dou uma apitadela  ?

Cumps,

Link to comment
Share on other sites

o objectivo é ter apenas um scanf ou gets que receba um comando completo e que de como resultado uma string com o nome do comando (por exmeplo: soma) e transforme todos os outros parametros em inteiros!

bem, vamos lá a organizarmo-nos lol :)

tipo estás a dizer que é perciso 1 scanf para tudo : soma 1 2 e ele devolver 3 ou estás a dizer que é soma (e usas 1 scanf) 1 (e outro) 2 (e outro)

Link to comment
Share on other sites

Se fizeres com scanfs para todos os valores, os parametros podem ser passados todos na mesma linha porque o C faz a divisão por si, logo não há problema.

Agora, se em vez de usares scanf("%s",s); (lê uma palavra, exactamente aquilo que tu queres) preferires usar o gets(s); (lê uma string, aquilo que tu pensas querer :) ) podes sempre transformar uma string em inteiro usando o atoi

Uma pesquisa por isso no google revela-te o resto

Link to comment
Share on other sites

epah é que se for o caso de poder usar os scanf's que quiser, que pleo que sei sao como os readln em Pascal fikaria assim: (em pascal)

program string_e_integer;
var
a:string
b,c,d:integer;
begin
read(a); read(b); read(c);
d:=b+c;
writeln(d);
end.
Link to comment
Share on other sites

se bem percebi, pretendes algo deste genero:

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


int separar_linha(char linha[80], char *comando, int *argumentos) {
unsigned int c_linha=0, indice=0, n_args=0;
char temp[20];

//extrai comando (1a palavra)
while( ((linha[c_linha]==' ') || (linha[c_linha]=='\t')) && (linha[c_linha]!=0) ) ++c_linha;

while( ((linha[c_linha+indice]!=' ') && (linha[c_linha+indice]!='\t')) && (linha[c_linha+indice]!=0) )
	++indice;

memcpy(comando, linha+c_linha, indice);
comando[indice]=0;

c_linha+=indice;
indice=0;

//extrai argumentos
while ((n_args<30) && (linha[c_linha]!=0)) {
	while( ((linha[c_linha]==' ') || (linha[c_linha]=='\t')) && (linha[c_linha]!=0) ) ++c_linha;
	if (linha[c_linha]==0) break;
	while( ((linha[c_linha+indice]!=' ') && (linha[c_linha+indice]!='\t')) && (linha[c_linha+indice]!=0) )
		++indice;

	memcpy(temp, linha+c_linha, indice);
	temp[indice]=0;

	argumentos[n_args++]=atoi(temp);

	c_linha+=indice;
	indice=0;
}

return n_args;
}

int main() {
char linha[80], comando[20];
int argumentos[30], count, resultado, n_args=0;
while (1) {
	printf("> ");
	gets(linha);

	n_args=separar_linha(linha, comando, argumentos);
	resultado=argumentos[0];

	if(_strcmpi(comando, "soma")==0) {
		if (n_args < 2) {
			printf("uso: soma <arg1> <arg2> [arg3...]\n\n");
			continue;
		}
		else for (count=1; count<n_args; ++count) resultado+=argumentos[count];
	}
	else if(_strcmpi(comando, "subtraccao")==0)
		if (n_args < 2) {
			printf("uso: subtraccao <arg1> <arg2> [arg3...]\n\n");
			continue;
		}
		else for (count=1; count<n_args; ++count) resultado-=argumentos[count];
	else if(_strcmpi(comando, "sair")==0) {
		printf("baibai\n");
		break;
	} else {
		printf("erro: \"%s\" comando desconhecido\n\n", comando);
		continue;
	}

	printf("o resultado e' %d\n\n", resultado);
}

return 0;
}

Isso não está muito optimizado, mas faz o pedido. E tem alguns problemas por causa do espaço limitado para linhas de comandos (máximo 80 caracteres), comandos (20), argumentos (20), e número máximo de argumentos (30), para os quais não é feita qualquer verificação a ver se cabem ou não... Além de outros em que não pensei ::)

Programar em C depois de habituado a C++ pode ser frustrante... ::)

Desaparecido.

Link to comment
Share on other sites

epah é que se for o caso de poder usar os scanf's que quiser, que pleo que sei sao como os readln em Pascal fikaria assim: (em pascal)

program string_e_integer;
var
a:string
b,c,d:integer;
begin
read(a); read(b); read(c);
d:=b+c;
writeln(d);
end.

Mesmo o que eu disses estaria mal pk o programa nao iria ler o espaço depois da string "soma" e o espaço depois do integer "1" ;)

Link to comment
Share on other sites

.....

será que é preciso tanto? :)

@Heirophant: A função scanf faz quase tudo o que tu queres..só o possível problema que podes ter é o número de argumentos ser variável

talvez seja mais fácil definires um valor exacto para o número de argumentos, por exemplo 3:

....
char comando[10];
int arg1, arg2, arg3;
scanf("%s %d %d %d",comando, &arg1, &arg2, &arg3);
....

com argumentos variáveis já é mais complicado, assumindo que obrigas cada parametro a tar separado por um espaço podes fazer qq coisa como:


char parametros[2000]; //variavel auxiliar que contem a string com os argumentos
int argumentos[100]; //variavel que contem os valores dos argumentos

char comando[10]; //comando
char argumento[10]; //variavel auxiliar para saber o numero de caracteres de cada argumento

int i, j;


scanf("%s %s",comando, parametros);

for(i=0,j=0; parametros[i] != '\0' ;j++){
  sscanf(parametros+i,"%d ",argumento);
  i += strlen(argumento) +1; //avança #caracteres do argumento +1(espaço em branco) na string
  argumentos[j] = atoi (argumento);
}

....
Link to comment
Share on other sites

Hehe, o meu departamento é mais C++... nunca fui grande conhecedor das várias versões dos scans e prints do C 😄 por isso inventei ::)

Mas assim:

scanf("%s %s",comando, parametros);

so lês o 1º parâmetro. Se fizeres

scanf("%s",comando);
gets(parametros);

já concordo. Mas tens outro problema na linha

  i += strlen(argumento) +1; //avança #caracteres do argumento +1(espaço em branco) na string

porque a menos que tenhas espaços no fim da string parametros, depois de leres o ultimo argumento vais ficar a apontar para um espaço que já não lhe pertence. O melhor é não adicionar 1:

  i += strlen(argumento); //avança #caracteres do argumento na string

Mas o código ficou muito melhor da tua maneira :)

Desaparecido.

Link to comment
Share on other sites

??

Isto pode ser tudo resolvido de um modo mt simples.

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

void soma() {
     int a,res=0;
     while (scanf("%d",&a)!=EOF) {
           res+=a;
     }
     printf("%d\n",res);
}

void mult() {
     int a,res=1;
     while (scanf("%d",&a)!=EOF) {
           res*=a;
     }
     printf("%d\n",res);
}

int main() {
    char s[30];
    scanf("%s",s);
    if (!strcmp(s,"soma")) soma();
    if (!strcmp(s,"multiplicao")) mult();
    system("pause");
    return 0;
}

Simplesmente leem primeiro a operação, depois leem os parametros individualmente consoante o que querem fazer.

Atenção que ele está a fazer a leitura até chegar ao final do ficheiro.

Logo, se quiserem testar, em windows, podem usar um input deste genero:

soma 1 3 5 4

ctrl + z

o ctrl+z simula um fim de ficheiro, e o programa pára. (pode-se usar outro tipo de verificação de final, mas esta é a mais usada)

Link to comment
Share on other sites

Heirophant

Muito obrigado pelas várias maneiras que sugeriram mas existe um problema.

Eu dei o exemplo da soma mas devo ter-me explicado mal.

Eu não vou usar a função soma, por isso esta é apenas um exemplo.

Eu queria que ao ler o comando e os parametros, ele separasse todxos os parametros e os converte-se em inteiros e que esses inteiros fossem passados a outra função. por exemplo à função soma (int a, int b). Ou seja depois de ser lido o comando, iniciava a função soma (a, b) (por exemplo).

E a função pode receber mais parametros! Pode receber 4 ou 5 parametros... (para outras funções). Porque tenho vários tipos de funções. Umas recebem 2, outras 3 e outras 4 parametros, por isso tem de haver uma condição que diga que: se o nº de parametros for maior ou menor do que o necessairo para usar na função X, dê um erro!

Se não conseguirem ajudar não faz mal, já ajudaram muito!

Obrigado mais uma vez

Link to comment
Share on other sites

por isso tem de haver uma condição que diga que: se o nº de parametros for maior ou menor do que o necessairo para usar na função X, dê um erro!

Isso está incluído no meu código. A função separar_args devolve o número de argumentos lidos, que depois é testado nos ifs encadeados:

	n_args=separar_linha(linha, comando, argumentos);

(...)

	if(_strcmpi(comando, "soma")==0) {
		if (n_args < 2) {
			printf("uso: soma <arg1> <arg2> [arg3...]\n\n");
			continue;
		}
		else for (count=1; count<n_args; ++count) resultado+=argumentos[count];
	}

Desta forma, se o número de argumentos da soma for inferior a 2, o programa dá uma mensagem com explicação de uso do comando.

Desaparecido.

Link to comment
Share on other sites

E da forma que eu fiz o efeito prático é igual, só que em vez de leres tudo na principal, e passares como parametros, é a função que faz a leitura.

Cada função depois controla individualmente o número de parametros que podem ser lidos, eu não coloquei isso no código.

Link to comment
Share on other sites

Heirophant

O problema é que no teu código não me devolve os parametros que eu quero. POr exemplo... no teu codigo diz que se o numero de parametros for menor do que dois, dá erro. Eu posso por que se for mais do que 2 dá erro também e assima função só funciona quando eu tiver 2 argumentos. Muito bem. O problema é que não me devolve os argumentos separados.

Por exemplo: se o comando fosse "soma 1 2"

Eu queria que chama-se a função soma( int a, int b) (declarada previamente).

Qualquer coisa do genero:

main ()

se comando==soma então

soma (a, b)

else erro.

em que o a e b eram retirados da leitura do comando!

eu queria que todos os parametros tirados do comando fossem transformados em inteiros individualmente!

será possivel isso?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.