Ir para conteúdo
Fórum Script Brasil
  • 0

Programacao AvanÇada Em C - Duvida & Desafio


Guest --JOAO --

Pergunta

Guest --JOAO --

PESSOAL ESTOU TENTANDO RESOLVER UM EXERCICIO EM C MAIS NÃO ESTOU CONSEGUINDO, REALMENTE NÃO ESTÁ FACIL, SERA QUE alguém PODERIA AJUDAR? TAMBEM FICA COMO DESAFIO PARA QUEM CONSEGUIR FAZE-LO:

ENUNCIADO:

desenvolver na linguagem C tres versoes de um programa que execute

operacoes matematicas elementares

as operacoes matematicas são: +,−, , /

um processo, dito cliente, le do teclado uma operacao matematica

envia a operacao a ser relizada, no seguinte formato: “operando

operador operando” (2 + 2)

o outro processo, dito receptor, recebe a descricao da operacao,

executa e envia resposta (4)

o cliente recebe resposta e exibe o resultado na tela

fazer uma versao que usa pipes, outra pipes nomeados e uma terceira memoria

compartilhada

ESTAVA FAZENDO O PRIMEIRO QUE USA SOMENTE PIPE SEGUE O CODIGO ABAIXO, MAIS NÃO ESTOU CONSEGUINDO SUCESSO...

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <string.h>

int n, fd[2];

/* recebe os numeros e a operação, calcula e devolve o resultado*/

void calcula(int n1, int n2, char op, int fd){

char saida[15];

int result;

switch(op){

case '+':

result=n1+n2;

break;

case '-':

result=n1-n2;

break;

case '/':

result=n1/n2;

break;

case '*':

result=n1*n2;

break;

}

/* imprimimos o resultado no fd */

sprintf(saida,"%d",result);

/* agora mandamos os bytes */

if (write(fd, saida, strlen(saida)) != strlen(saida) ) {

fprintf(stderr, "Erro na escrita no pipe (saida=%s)\n",saida);

}

}

int main(int argc, char *argv[]){

int fd[2];

pid_t pid;

int n1,n2,result;

n1=atoi(argv[1]);

n2=atoi(argv[3]);

/* cria pipe */

if (pipe(fd) < 0) {

perror("Problema na criacao do pipe");

exit(1);

}

if ( (pid = fork() ) < 0) {

perror("Problema no fork");

exit(1);

}else if ( pid > 0 ) {

/* pai */

close (fd[0]); /* fecha o lado da leitura */

calcula(n1,n2,*argv[2],fd[1]); /* gera o resultado(saida) escrevendo-a no pipe */

/* terminada a saida, fechamos este lado de writing do pipe */

close(fd[1]);

/* esperamos pela terminacao do filho */

if (waitpid (pid, NULL, 0) < 0) {

fprintf(stderr, "Erro no waitpid");

exit(1);

}

/* pai sai normalmente */

exit(0);

}

else {

/* filho */

close(fd[1]); /* fecha o lado de escrita */

/* queremos chamar dup2 para associar lado de leitura

** do pipe com stdin, mas temos que tomar cuidado para

** o lado do pipe já' ser o proprio stdin. Lembremos

** da definicao de dup2(filedes, filedes2) :

** dup2 causa o file descriptor filedes2 se referir

** a mesma coisa que files. Se filedes2 se refere a

** um file descriptor já' aberto e diferente de filedes,

** então ele e' primeiro fechado.

** Portanto, queremos fechar que stdin seja fechado no

** caso de fd[0] já' ser o stdin. Voce acha que seria

** possivel, ou seja, que fd[0] poderia ser o stdin quando

** criado pelo pipe() ? Bem, e' possivel se o shell não

** criou o fd 0 como sendo o stdin, pois ai' pipe acharia

** que este valor (menor file descriptor não usado) estaria

** livre. Mas deveria ser improvavel ...

*/

if (fd[0] != STDIN_FILENO) {

/* diferentes, então podemos chamar sem perigo */

if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) {

fprintf(stderr, "dup2 error para stdin");

exit(1);

}

close(fd[0]); /* não e' necessario mais */

}

}

Link para o comentário
Compartilhar em outros sites

Posts Recomendados

  • 0
Guest --JOAO --

esse é o problema não sei o que esta errado simplesmente não funciona !!

será que você poderia verifiar o codigo e me dizer o que esta errado?

obrigado !!

Link para o comentário
Compartilhar em outros sites

  • 0

nada, o código está correto.

olha só o conteúdo do tubo de leitura.

acrescente isso no seu código.

if (fd[0] != STDIN_FILENO) {
/* diferentes, então podemos chamar sem perigo */
       FILE *stream;
       int c;
       stream = fdopen (fd[0], "r");
       while ((c = fgetc (stream)) != EOF)
         putchar (c);
       fclose (stream);
//       if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) {
//         fprintf(stderr, "dup2 error para stdin");
//        exit(1);
//   }
// close(fd[0]); /* não e' necessario mais */
      }

Link para o comentário
Compartilhar em outros sites

  • 0
cara funcionou ai pra ti? apareceu o resltado?

quando executa ex: pipe 5 + 3

aparece na tela 8 ?

funciona.

olha só, observa seu prompt o primeiro caracter depois de executar o comando.

Link para o comentário
Compartilhar em outros sites

  • 0
Guest --JOAO --

ah e verdade heheeh, cara valeu ai pela dica !!!

o primeiro foi, agora quero ver como vai ser os outros 2 alguma ideia de como fazer os outros 2?

não sei nem como começar....

Link para o comentário
Compartilhar em outros sites

  • 0
fazer uma versao que usa pipes, outra pipes nomeados e uma terceira memoria compartilhada

pipes nomeados? o que seria?

com memoria compartilhada voce vai usar funcoes como:

shmget

shmat

shmdt

leia o manual das funcoes. Ex:

man shmget

Link para o comentário
Compartilhar em outros sites

  • 0
Guest --JOAO --

cara os pipes nomeados usam mkfifo() mknode()

exemplo de chamada do sistema: mkfifo ("myPipe", 0660)

independentemente, do resultado a criacao de um arquivo especial

apos abertura do pipe nomeado usando open(), são feitas operacoes

de leitura e escrita

write() escreve no fim do pipe, e read() le da cabeca (FIFO)

close() e usado para fechar o pipe, e se o pipe não sera mais usado,

então deve ser removido com unlink()

como ficaria sera?

Link para o comentário
Compartilhar em outros sites

  • 0
como ficaria sera?

que tal criar dois executáveis, um que le fifo e outro que escreve.

o que le o fifo voce pode fazer com que ele fique num loop: abre o fifo, le o conteudo, exibe na tela, fecha arquivo.

e o que escreve no fifo: lê os argumentos, faz o cálculo, abre o fifo, envia o resultado, fecha o fifo.

Link para o comentário
Compartilhar em outros sites

  • 0
Guest --JOAO --

bhaa estava terminando os testes aqui do primeiro, mais esta dando erro

quando faço uma multiplicação

por ex: eu fiz $ ./pipe2 4 * 2

aparece pra mim: 4497856

que loucura !!! devia funcionar como os outros, não acho o erro...

Link para o comentário
Compartilhar em outros sites

  • 0

acho que funcionaria, mais como eu faria isso?
cara, não é muito dificil tenta fazer ai alguma coisa algumas dicas: do que lê
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <linux/stat.h>
.
.
.
   umask(0); // seta umask 0
   mknod("arquivo_fifo", S_IFIFO|0666, 0); // da permissao para leitura e escrita para todos usuários

   while(1){
      // abre o arquivo
      // le o conteudo
      // exibe na tela
      // fecha arquivo
   }
.
.
.

voce sabe fazer o que falta.

Link para o comentário
Compartilhar em outros sites

  • 0
Guest --JOAO --

hauahauahauhauuhaahu

caraca !! hehheehhe meu valeu mesmo ai pela força

vou tentar fazer os outros dois depois posto aqui

valeu !!

ahh quem quiser se habilitar em fazer também o desafio da foi lançado hehhehehe

abraços

Link para o comentário
Compartilhar em outros sites

  • 0
Guest --JOAO --

está bom eu vou tentar fazer, é que não entendi como funciona esses outros dois.. por isso que eu pedi pra ti postar, por que dai eu poderia entender melhor não qro simplesmente pegar o codigo e era isso, dai ql o prazer de programar?

Link para o comentário
Compartilhar em outros sites

  • 0
está bom eu vou tentar fazer, é que não entendi como funciona esses outros dois.. por isso que eu pedi pra ti postar, por que dai eu poderia entender melhor não qro simplesmente pegar o codigo e era isso, dai ql o prazer de programar?

se voce tentar eu te ajudo e se for preciso posto o código pronto, caso contrário nada feito.

Link para o comentário
Compartilhar em outros sites

  • 0
Guest --JOAO --

tranquilo velho vou fazer aqui depois posto o que eu conseguir, estou com um problema não estou com linux aqui no trb ai fica meio dificil para fazer os testes, mais vou fazer igual...

valeu pela ajuda !!

Link para o comentário
Compartilhar em outros sites

  • 0
Guest --JOAO --

terminei o 2, mais não sei se funciona, não tenho compilador aqui pra testar, crie dois aquivos o writer e o reader segue o codigo:

writer.c


/* pipe named. autor: Rodrigo Scorsatto and Juliano Flores*/

#include <stdio.h>
#include <fcntl.h>


main()
{

int n1=0,n2=0,result;
int fd,operacaolen;
char aux[20];
char Buff[20];

printf("digite a operacao ");
fgets(aux,20,stdin);

strcpy(Buff,aux);
/* Prepare operação */
sprintf (Buff, Buff, getpid ());
operacaolen=strlen (Buff) + 1;
do /* Keep trying to open the file until successful */
{
fd = open ("aPipe", O_WRONLY); /* Open named pipe for writing */
if (fd == -1) sleep (1); /* Try again in 1 second */
}
while (fd == -1);
/* Send operacao */
{
write (fd, Buff, operacaoLen); /* Write message down pipe */
sleep (3); /* Pause a while */
}
close (fd); /* Close pipe descriptor */


[/codebox]

reader.c

[codebox]#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int calcula(char str[20]){

int resultado=0,n1=0,n2=0,cont=0;
char delims[] = " ";
char *result = NULL;
char op;
result = strtok ( str, delims );
n1=atoi(result);
while( result != NULL ) {
if (cont==1){
op=*result;
}else if(cont==2){
n2=atoi(result);
}
cont++;
result = strtok( NULL, delims );
}
printf("%d",n1);
printf("%c",op);
printf("%d",n2);

switch(op){
case '+':
resultado=n1+n2;
break;
case '-':
resultado=n1-n2;
break;
case '/':
resultado=n1/n2;
break;
case '*':
resultado=n1*n2;
break;
}
return resultado;
}



main()
{

int n1=0,n2=0,result;

int fd;
char operacao[20];

mkfifo ("aPipe", 0660); /* Create named pipe */
fd = open ("aPipe", O_RDONLY); /* Open it for reading */
while (readLine (fd, operacao)) /* Display received messages */
//printf ("%s\n", str);
result=calcula(operacao); /*recebe a operacao ex: 2 + 4*/ ,
printf("Resultado: %d",result);
close (fd); /* Close pipe */

}

readLine (fd, str)
int fd;
char* str;
/* Read a single NULL-terminated line into str from fd */
/* Return 0 when the end-of-input is reached and 1 otherwise */
{
int n;
do /* Read characters until NULL or end-of-input */
{
n = read (fd, str, 1); /* Read one character */
}
while (n > 0 && *str++ != 0);
return (n > 0); /* Return false if end-of-input */
}

poderia verificar se tem algum erro? ou se eu estou fazendo alguma coisa errada?

valeu !!

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,1k
    • Posts
      651,8k
×
×
  • Criar Novo...