Jump to content

Recommended Posts

Posted (edited)

vou receber do utilizador

Esclarece melhor a tua dúvida.

Vais ler essa string do utilizador, ou recebê-la por parâmetro da linha de comandos?

vou receber a string do utilizador

Edited by analuisavilas
Posted

pods ser mais clara no que realmente queres ?

é que uma afirmação dessas não faz muito sentido ...

exemplo: "ls -al " é uma string introduzida pelo utilizador

msh > ls -al

comando : 1

nome: ls

parametro .al

msh > -al | more

comando 1

nome : ls

parametro : -al

comando 2

nome: more

msh> ls-al | wc -c > teste

comando 1

nome : ls

parametro : -al

comando 2

nome: wc

parametro -c

stout : teste

Posted

Tens de ter em atenção 2 caracteres, o ' ' (espaço) que te separa os argumentos, e o '|' (pipe) que te separa comandos.

Isto pode ser feito usando o strtok, em 2 passagens, separando os vários comando apenas usando o '|', e depois voltando a correr o strtok sobre cada substring, para separa os comandos dos argumentos.

Um exemplo:

ls -al | more

2 passagens:

Tendo a variável:

char *comandos[];

Fazes o strtok com o parametro delim = "|"

ficas com:

comandos[0] = "ls -la"

comandos[1] = "more"

se depois voltares a aplicar o strtok com o parametro delim = " "

ficas com o comando no primeiro token, e os argumentos nos seguintes.

PS: Isto sem ter em conta os < e > para diferenciar input e output de parâmetros. Aí terás de usar mais passagens, pois com o strtok não é possível saber qual o caracter que gerou o match, se não estou enganado.

  • Vote 1
Posted (edited)

Tens de ter em atenção 2 caracteres, o ' ' (espaço) que te separa os argumentos, e o '|' (pipe) que te separa comandos.

Isto pode ser feito usando o strtok, em 2 passagens, separando os vários comando apenas usando o '|', e depois voltando a correr o strtok sobre cada substring, para separa os comandos dos argumentos.

Um exemplo:

ls -al | more

2 passagens:

Tendo a variável:

char *comandos[];

Fazes o strtokcom o parametro delim = "|"

ficas com:

comandos[0] = "ls -la"

comandos[1] = "more"

se depois voltares a aplicar o strtok com o parametro delim = " "

ficas com o comando no primeiro token, e os argumentos nos seguintes.

PS: Isto sem ter em conta os < e > para diferenciar input e output de parâmetros. Aí terás de usar mais passagens, pois com o strtok não é possível saber qual o caracter que gerou o match, se não estou enganado.

consegui fazer assim , mas nao sei fazer o resto, ou seja nao sei colocar a parte dos prinst, a dizer : parametros, comando, etc

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

int main(int argc, char *argv[])
{
 char frase[200] = " ls -al";
 char *parte;


  parte = (char*)strtok(frase, " ");


 while(parte != NULL){
printf("%s\n", parte);
parte = (char*)strtok(NULL, " ");
 }

 printf("\n\n");
 system("pause");
 return 0;
}
Edited by analuisavilas
Tags code + GeSHi
Posted

Atenção que assim não apanhas os "|", não tendo hipótese de diferenciar diferentes comandos.

O que estás a fazer é separar a linha em palavras. Tenta com a frase "ls -la|more" a ver o que te dá (e mantém os espaços como os tenho).

Outra hipótese que tens, visto que tens montes de símbolos, é fazeres um parse manual, isto é, leres caracter a caracter da string e decidires com base em cada caracter o que vem a seguir.

A forma mais correcta de fazeres isso é usares algum tipo de estrutura mais complexa para guardares os vários resultados.

Sabes que um comando tem: Comando Parâmetros Input Output .

podes criar uma estrutura comando, com estes campos, e depois guardares tudo num array de comando. Atenção que isto é só um exemplo.

Posted

é fazeres um parse manual

desnecessário, basta usar estados

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

int main(int argc, char *argv[])
{
 char frase[200] = "ls -al | more";
 char *parte;
 int state = 0;

 parte = (char*)strtok(frase, " ");
 while(parte != NULL){
   if (strcmp("|", parte) == 0) {
     printf("pipe\n");
     state = 0;
   } else if (!state) {
     printf("comando : %s\n", parte);
     ++state;
   } else {
     printf("parametro : %s\n", parte);
   }

   parte = (char*)strtok(NULL, " ");
 }

 return 0;
}
IRC : sim, é algo que ainda existe >> #p@p
Posted

Pois, não usas o pipe como um delimitador, assim consegues verificar a sua ocorrência. No entanto se retirares os espaços, como tenho na string que postei, estes são os resultados:

comando : ls
parametro : -al|more

Se calhar estou eu a complicar um bocado a coisa, mas normalmente era com esses pontos que os meus profs implicavam. Lembro-me de me terem chateado porque um simples exercício de contagem de palavras não funcionava se as palavras estivessem separadas por tabs 😛

Posted

desnecessário, basta usar estados

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

int main(int argc, char *argv[])
{
 char frase[200] = "ls -al | more";
 char *parte;
 int state = 0;

 parte = (char*)strtok(frase, " ");
 while(parte != NULL){
if (strcmp("|", parte) == 0) {
  printf("pipe\n");
  state = 0;
} else if (!state) {
  printf("comando : %s\n", parte);
  ++state;
} else {
  printf("parametro : %s\n", parte);
}

parte = (char*)strtok(NULL, " ");
 }

 return 0;
}

Boa noite,

Queria aproveitar este tópcio para esclarecer uma dúvida no código do HappyHippyHippo.

Acham que me podem explicar este passo do código:

else if (!state) {
printf("comando : %s\n", parte);
++state;
}

Desde já obrigado.

Posted (edited)

Quando state é 0, significa que tens o comando. Nesse caso, indicas o comando e incrementas state. A partir daqui, tudo o que vier a seguir são parâmetros.

!state é uma abreviatura de state == 0. Como em C não tens valores booleanos, representas a veracidade com inteiros - 0 é falso e outro número é verdadeiro. O if é executado caso a condição seja verdadeira. Neste caso, nós queremos analisar quando state é 0, e 0 é o equivalente a falso. Portanto, nós temos de indicar not false, ou seja, !state, o mesmo que !(state <> 0).

Esclareci a tua dúvida? 🙂

Edited by thoga31
  • Vote 1

Knowledge is free!

Posted

Quando state é 0, significa que tens o comando. Nesse caso, indicas o comando e incrementas state. A partir daqui, tudo o que vier a seguir são parâmetros.

!state é uma abreviatura de state == 0. Como em C não tens valores booleanos, representas a veracidade com inteiros - 0 é falso e outro número é verdadeiro. O if é executado caso a condição seja verdadeira. Neste caso, nós queremos analisar quando state é 0, e 0 é o equivalente a falso. Portanto, nós temos de indicar not false, ou seja, !state, o mesmo que !(state <> 0).

Esclareci a tua dúvida? 🙂

Muito obrigado thoga31. 🙂 Percebi muito bem, foi super esclarecedor. 👍😁

Posted

Atenção que assim não apanhas os "|", não tendo hipótese de diferenciar diferentes comandos.

O que estás a fazer é separar a linha em palavras. Tenta com a frase "ls -la|more" a ver o que te dá (e mantém os espaços como os tenho).

Outra hipótese que tens, visto que tens montes de símbolos, é fazeres um parse manual, isto é, leres caracter a caracter da string e decidires com base em cada caracter o que vem a seguir.

A forma mais correcta de fazeres isso é usares algum tipo de estrutura mais complexa para guardares os vários resultados.

Sabes que um comando tem: Comando Parâmetros Input Output .

podes criar uma estrutura comando, com estes campos, e depois guardares tudo num array de comando. Atenção que isto é só um exemplo.

Boa tarde,

O meu problema é mesmo esse, é que tenho que verificar a string quer tenha espaços ou não, e tem que verificar também o stdin e o stdout. A melhor forma de o fazer é com uma estrutura? Acham que me podem auxiliar a resolver.

Obrigado.

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