• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Heirophant

leitura de string do teclado

24 mensagens neste tópico

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á

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tem de ser obrigatoriamento declarados como Char ou String ou TU estipulaste que era melhor que assim fosse ?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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, 

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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" :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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  :ipool:

Cumps,

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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... ::)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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" ;)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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);
}

....

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Hehe, o meu departamento é mais C++... nunca fui grande conhecedor das várias versões dos scans e prints do C :D 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 :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

É pá daqui a pouco chega alguém que faz o programa todo numa só linha e o iniciador da thread não diz nada ::)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros 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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Desculpa lá, não estou a compreender... já viste bem todo o código que foi aqui escrito? Vou só falar no meu, cada um que defenda o seu :D

Se queres que a soma receba dois e só dois argumentos, é só alterar a linha

if (n_args < 2) {

para

if (n_args != 2) {

Além disso, todos os argumentos vão separados como ints no array argumentos... em cada indice está um argumento, sendo que em argumentos[0] está o 1º, em argumentos[1] o segundo (...) e em argumentos[n_args - 1] está o último...

Se queres chamar uma função, digamos a função soma, com os 2 primeiros argumentos passados pelo comando soma, é só fazer

soma(argumentos[0], argumentos[1]);

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Se queres chamar uma função, digamos a função soma, com os 2 primeiros argumentos passados pelo comando soma, é só fazer

Código

GeSHi ©:

soma(argumentos[0], argumentos[1]);

-------------------------------------------------

Era isso que eu não sabia se podia fazer! Desculpa a ignorancia! Muito obrigado mais uma vez!!!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não é ignorância, e não tens de pedir desculpa :thumbsup: estamos cá todos para aprender :D

Desculpa peço eu se fui bruto. Era já o sono a falar... :-[

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

há alguma possbilidade de pôr essa função a ler e guardar argumentos de texto também?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora