Ir ao conteúdo
  • Cadastre-se

C Linguagem C problema em resolver o código


Andrah

Posts recomendados

Usar setbuf(stdin, buffer) cria o problema de impossibilitar redirecionar a entrada de dados.

 

Por exemplo se quiser redirecionar a saída de texto de um programa como entrada do programa que está programando (isso é algo muito útil e poderoso, muito usado em programas de terminal, no Linux principalmente tem vários programas de terminal que podem ser usados para fazer coisas bem complexas quando combinados).

 

Outro exemplo de redirecionamento seria para passar os dados de entrada do programa através de um arquivo de texto com os dados a serem digitados, ao invés de digitar manualmente durante a execução do programa, fazendo algo como:

programa.exe < arquivo_entrada_de_dados.txt

 

Nesses casos o setbuf(stdin, buffer) vai resetar a stdin inteira, perdendo todo o restante da informação que foi passada como entrada através do arquivo.

 

 

Então eu diria que o método usando a função abaixo ainda é a melhor opção:

void flush(){
    int c;
    /*Lê todos os caracteres até encontrar '\n' ou EOF:*/
    while( (c = getchar()) != '\n' && c != EOF );
}

Só precisa saber usar corretamente nos locais certos.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

17 horas atrás, isrnick disse:

Usar a função setbuf(stream, buffer) é uma abreviação de usar setvbuf(stream, buffer, _IOFBF, BUFSIZ) , note que já é assumido o tamanho BUFSIZ para o buffer, se quiser usar um buffer com tamanho diferente terá que usar a função setvbuf() diretamente alterando o último parâmetro, ao invés de setbuf().

 

Outro problema é que você declarou o buffer dentro da função main, mas para stdin e stdout tem que ser declarado no escopo global, pois os streams de entrada só deve ser fechado quando o programa for finalizado, mas o buffer dentro do main será finalizado quando a função main acabar (e o stdin/stdout vai ficar sem buffer).

 

Nesse caso acho que não dá pra ficar com o que diz https://en.cppreference.com/w/c/io/setbuf
 

Não está correto. De todo modo essa parte é importante: 

This function may only be used after stream has been associated with an open file, 
but before any other operation (other than a failed call to setbuf/setvbuf).

A common error is setting the buffer of stdin or stdout to an array whose
 lifetime ends before the program terminates

E essa

image.thumb.png.64e51ec9667806f2fde287c27e125643.png



Do mesmo lugar. Esse acho que é "o mapa da mina". E atente para o "may" e entenda que isso não afeta o sistema operacional e então buffers como o do terminal xterm podem atuar antes do buffer usado por stdlib / STL...

 

 

2 horas atrás, isrnick disse:

Usar setbuf(stdin, buffer) cria o problema de impossibilitar redirecionar a entrada de dados.

 

Por exemplo se quiser redirecionar a saída de texto de um programa como entrada do programa que está programando (isso é algo muito útil e poderoso, muito usado em programas de terminal, no Linux principalmente tem vários programas de terminal que podem ser usados para fazer coisas bem complexas quando combinados).

 

Eu me lembro de casos onde setbub(0 ou setvbuf(0 era importante. E eram casos de comunicação serial ou via TCP ou X.25. Sim X.25 dos tempos muito pré-internet :) 

 

setvbuf() faz sentido quando você precisa adequar o buffer de um fluxo --- stream --- para alguma realidade. E muitas dessas realidades são a razão de usar C ou C++ hoje em dia. Buffers de comunicação com chips ou com mainframes ou com bancos de dados, programas de comunicação e coisas assim. 

 

Um exemplo meio off-topic mas que vai dar um contexto de onde se precisa de algo desse tipo: se alguém usa ou usou o comando dd no Linux ou mesmo no Windows, pode ter visto os parâmetros ibs, obs e bs que são os tamanhos dos buffers usados. Isso tem um efeito digamos dramático nos tempo s de execução ao você tentar copiar por exemplo um arquivo de muitos gigabytes de um lugar para outro. E é muito fácil de testar os parâmetros e ver o quando muda no tempo de cópia. Tente duplicar um pen-drive Linux de 64GB e escolha um buffer pequeno...
 

image.png.4fdd593615484101e6753adda88dd2d2.png

 

Muito bem, dd trabalha com arquivos, foi escrito em C e é um candidato a usar setvbuf() com boa razão.

 

setvbuf() e stdin, stdout e stderr

 

Não há razão para usar setvbuf() com os fluxos padrão 0,1 e 2 a menos que eles estejam redirecionados. Mesmo que o compilador aceite e o programador fique feliz por ter feito uma alteração mais íntima no comportamento do sistema. Provavelmente é inócuo.

 

Em geral programas em C de produção não falam com esses fluxos. Talvez stderr para gravar log em algum caso. Mas é preciso entender que stdin, stdout e stderr, pensando em programas interativos, são coisas de velocidade absolutamente irrelevante. Hoje um processador de computador doméstico tem mais de 1.5 bilhão de transistores, um telefone tem 4 ou 8 núcleos e roda milhões de instruções por segundo. Esperar por um prompt ou colocar algo numa tela é irrelevante.

 

Você usa isso --- setvbuf() --- por exemplo se vai redirecionar a saída padão de um Arduino para um display LCD e quer o buffer próximo do tamanho do buffer que o LCD usa. Assim o sistema faz um flush() automaticamente dos dados quando a mensagem está completa, ou situações similares.

 

não há razão para isso funcionar em 0, 1 ou 2. Nem mesmo se pretende desabilitar buffering totalmente porque o sistema provavelmente vai ignorar.

 

É algo chato pra testar e não compensa. Eu ao menos não tenho essa motivação a menos de algum cheque ;) 

 

Vejam por exemplo o que a IBM diz no compilador dos mainframes de hoje em dia
 

setvbuf.thumb.png.1e4f54b3229eb13d5d5203e49d89d1c0.png

 

(Em https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/rtref/setbuf.htm)

 

 Ou a Microsoft

  

msset.png.a56e9bf1d283765c123a25af25313ee2.png

 

Claro, setvbuf() é uma dessas rotinas.

 

Em programas de hobby ou de estudantes não há razão para perder tempo com isso. A menos que esses fluxos sejam redirecionados, como em programas de cópia de arquivos que podem ser grandes, ou programas que falam com chips ou periféricos como o exemplo de que falei --- Arduino, Raspberry Pi...

 

Meu palpite apenas

 

image.png

adicionado 2 minutos depois

Como está seu programa agora? Ainda precisa de algo?

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

1 hora atrás, vangodp disse:

E você...? Entendeu que funciona também o fgets+sscanf?

 

?

Fico em dúvida se está falando sério. Chamar uma variável local de buffer e usar scanf() para ler dela não mostra nada. O prefixo s é de storage, como deve saber, em sscanf() Você apenas leu tudo para uma área intermediária que aproveitou para chamar de buffer. O buffer de que se fala na literatura e é alvo de setvbuf() é uma área de armazenamento do sistema. Talvez pudesse falar de ungetc() que de fato existe e faz isso...

 

PeekConsoleInput() é outro bicho

BOOL WINAPI PeekConsoleInput(
  _In_  HANDLE        hConsoleInput,
  _Out_ PINPUT_RECORD lpBuffer,
  _In_  DWORD         nLength,
  _Out_ LPDWORD       lpNumberOfEventsRead
);

E permite inspecionar o buffer antes de ler.

 

Não tem nenhum paralelo com o que está dizendo. Você usa isso na prática quando seu programa está fazendo algo em um loop. Seu programa single-thread, comum. E você precisa ler da entrada. Mas não pode ler da entrada porque vai parar o programa. Então você usa essa função para só ler quando sabe que tem algo. Pense em um game por exemplo.

 

Ler tudo para uma variável local que você chamou de buffer é folclórico, mas é diferente. Acho que entendeu. Ou não?

 

1 hora atrás, vangodp disse:

Vou lhe mostrar o que ta no buffer sem usar essa função peek

 

:D Só que você já leu. Aí vai apontar toda a leitura de seu programa para essa outra variável. Que até tem o nome de buffer. E criou uma nova camada com o mesmo problema.

 

E se seu programa for multi-thread então pode ter consumido uma entrada que não era para o particular thread que leu o buffer. E aí vai ter que criar uma nova camada em seu programa para alimentar isso. Pense bem. Está mesmo falando sério ou só me testando...

Link para o comentário
Compartilhar em outros sites

2 minutos atrás, Andrah disse:

E o meu programa ninguém vai me ajudar?

Notou o que perguntei antes do almoço? ;) 

 

Mas você tem razão se acha que seu tópico foi "invadido" por discussões meio estranhas. Vou parar. Escreva com a situação atual

adicionado 0 minutos depois
2 horas atrás, arfneto disse:

Como está seu programa agora? Ainda precisa de algo?

 

isso. @Andrah

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

4 minutos atrás, arfneto disse:

Notou o que perguntei antes do almoço? ;) 

Não porque sou iniciante em programação algumas coisas não entendi mas aprendi muito. Obrigado.

 

adicionado 3 minutos depois
3 minutos atrás, herbertbahia disse:

Haha quanto mais vocês discutem mais eu aprendo

kkkk verdade isso! 

5 minutos atrás, herbertbahia disse:

system("TYPE \"funcionarios.txt");

Obrigado 

vou colocar no programa :) 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

:) 

Como está seu programa agora? Ainda precisa de algo?

 

Isso foi o que eu perguntei. 3 vezes agora desde antes do almoço. Poste o programa como está agora e alguma dificuldade que tenha.

 

Se se interessou por algo dessas "discussões meio paralelas" mas não compreendeu simplesmente como um ato de vingança "invada"  a discussão paralela e pergunte algo :)

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

1 minuto atrás, arfneto disse:

Como está seu programa agora? Ainda precisa de algo?

Sim precisa é que as funções não estão certas acho e ainda falta fazer algumas funções para colocar nos cases 

3 minutos atrás, arfneto disse:

Isso foi o que eu perguntei. 3 vezes agora desde antes do almoço. Poste o programa como está agora e alguma dificuldade que tenha.

O programa tá igual não estou conseguindo resolver 

//bibliotecas
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include <conio.h>
#include <time.h>

//Dados do funcionário
struct Funcionario {
    char nome[20];
    char NIF[20];
    char categoria[20];
    float salario;
    int Hora_Trabalhados;
};

// Para não atrapalhar o bom funcionamento
void menu ( struct Funcionario funcionario[], int n );

void pressioneEnter() {
    char c;

    do {
        c = getch();
    } while ( c != 13 );
}

void flush() {
    int c;
    /*Lê todos os caracteres até encontrar '\n' ou EOF:*/
    while( (c = getchar()) != '\n' && c != EOF );
}

void IncerirFuncionario ( struct Funcionario funcionario[], int n ) {
    system ( "COLOR 0F" );
    FILE *file; // cria variável ponteiro para o arquivo
    file = fopen ( "funcionarios.txt", "w" ); //abrindo o arquivo

    if ( file == NULL ) //testando se o arquivo foi realmente criado
        printf ( "\n-->Nao foi possivel abrir o fecheiro\n\n" );
    else {
        printf ( "\n\n\n\n\tUNICV \n\n" );
        printf ( "\n\n\n\t\tDigite o numero de Funcionarios que pretende registrar: " );
        scanf ( " %i", &n );
        flush ();
        system ( "cls" );
        static int i = 0;
        int y = n + i;

        if ( y > 99 )
            menu ( funcionario, n );

        printf ( "\n\n\n\t\t-------- INSCRIÇÃO DE FUNCIONÁRIO --------\n\n" );
        fprintf ( file, "\n\n\t----- LISTA DOS FUNCIONÁRIOS ----\n\n" );
        fprintf ( file, "\tNome      NIF 	  Salário     Categoria    Horas\n\n" );

        for ( ; i < y; i++ ) {
            system ( "COLOR 0B" );
            // para obter dados e armazenar no arquivo
            printf ( "\n\tDigite o nome do funcionário: " );
            scanf ( " %s", funcionario[i].nome );
            flush ();
            printf ( "\n\tDigite o NIF do funcionário: " );
            scanf ( " %s",funcionario[i].NIF );
            printf ( "\n\tDigite o salario do funcionario: " );
            scanf ( " %f", &funcionario[i].salario );
            flush ();
            printf ( "\n\tDigite a categoria do funcionário: " );
            scanf ( " %s", funcionario[i].categoria );
            printf ( "\n\tDigite a Hora trabalhados pelo funcionário: " );
            scanf ( " %d", &funcionario[i].Hora_Trabalhados );
            printf ( "\n\n" );
            //A Escrevendo no arquivo
            fprintf ( file, "\t%s \t %s \t %.1f \t %s\t %d\n", funcionario[i].nome, funcionario[i].NIF, funcionario[i].salario, funcionario[i].categoria, funcionario[i].Hora_Trabalhados );
        }

        printf ( "\n\t\t-------------------------<3--------------------------\n" );
        printf ( "\n\t Incritos com sucesso! \n\n\t Registado no fecheiro -> funcionarios.txt\n\n" );
        printf ( "\n\n\n\t\t\tPressione ENTER para Continuar->" );
        flush ();
        pressioneEnter();
        system ( "cls" );
        menu ( funcionario, y );
    }

    fclose ( file ); // para fechar o arquivo
}

void ImprimirFuncionarios ( struct Funcionario funcionario[], int n ) {
    FILE *file;

    file = fopen ( "C:\\Users\\alex\\Desktop\\ajuda\\funcionarios.txt", "r" );

    if ( file == NULL )
        printf ( "\n-->Nao foi possivel abrir o fecheiro\n\n" );

    else {
        int i;
        printf ( "\n\n\n\t\t------- LISTA DOS FUNCIONÁRIOS ------\n\n" );

        for ( i = 0; i < n; i++ ) {
            system ( "COLOR 0F" );
            fscanf ( file, " %s", funcionario[i].nome );
            fscanf ( file, " %s", funcionario[i].NIF );
            fscanf ( file, " %f", &funcionario[i].salario );
            fscanf ( file, " %s", funcionario[i].categoria );
            fscanf ( file, " %d horas", &funcionario[i].Hora_Trabalhados );
            printf ( "\n\tNome: %s", funcionario[i].nome );
            printf ( "\n\tNIF: %s", funcionario[i].NIF );
            printf ( "\n\tSalario: %.1f $00", funcionario[i].salario );
            printf ( "\n\tCategoria: %s", funcionario[i].categoria );
            printf ( "\n\tHoras de trabalho: %d horas", funcionario[i].Hora_Trabalhados );
            printf ( "\n\n----------------------------------------------------------\n" );
        }
    }

    printf ( "\n\n\n\t\t\tPressione ENTER para Continuar->" );
    flush ();
    pressioneEnter();
    system ( "cls" );
    fclose ( file );

}

void OrdenarFuncionario ( struct Funcionario *funcionario, int n ) {

    int i, j;
    struct Funcionario aux;

    for ( i = 1; i < n; i++ ) {
        aux = funcionario[i] ;

        for ( j = i; ( j > 0 ) && ( aux.salario < funcionario[j - 1].salario ); j-- ) {
            funcionario[j] = funcionario[j - 1];
            funcionario[j] = aux;
        }

    }

    printf ( "\n\n\n\t------- LISTA DOS FUNCIONÁRIOS POR ORDEM CRESCENTE ------\n\n" );

    for ( i = 0; i < n; i++ ) {

        printf ( "\n\tNome: %s", funcionario[i].nome );
        printf ( "\n\tNIF: %s", funcionario[i].NIF );
        printf ( "\n\tSalario: %.1f $00", funcionario[i].salario );
        printf ( "\n\tCategoria: %s", funcionario[i].categoria );
        printf ( "\n\tHoras de trabalho: %d horas", funcionario[i].Hora_Trabalhados );
        printf ( "\n\n----------------------------------------------------------\n" );

    }

    printf ( "\n\n\n\t\t\tPressione ENTER para Continuar->" );
    flush ();
    pressioneEnter();
    system ( "cls" );
}


void EliminarFuncionario ( struct Funcionario funcionario[], int n ) {
    FILE *file;

    //Abre o arquivo novamente para leitura
    file = fopen ( "funcionarios.txt", "r+" );

    if ( file == NULL )
        printf ( "\n-->Nao foi possivel abrir o fecheiro\n\n" );

    else {
        int i;
        char nif;
        char resp;
        printf ( "\n\tInforme o NIF do funcionario a ser Eliminado: " );
        scanf ( " %d", &nif );

        while ( funcionario[i].NIF == nif ) {

            if ( funcionario[i].ativo== 1 ) {

                printf ( "\n\tNome: %s", funcionario[i].nome );
                printf ( "\n\tNIF: %s", funcionario[i].NIF );
                printf ( "\n\tSalario: %.1f $00", funcionario[i].salario );
                printf ( "\n\tCategoria: %s", funcionario[i].categoria );
                printf ( "\n\tHoras de trabalho: %d horas", funcionario[i].Hora_Trabalhados );
                printf ( "\n\n----------------------------------------------------------\n" );
            }
            printf ( "\n\tDeseja realmente eliminar o Funcionário? S/N:" );
            scanf ( " %c", &resp );

            if ( ( resp == 'S' ) || ( resp == 's' ) ) {
                funcionario[i].ativo=0;
                printf ( "\n\tFuncionário eliminado com sucesso\n" );
                break;
            } else {
                if ( ( resp == 'N' ) || ( resp == 'n' ) ) {
                    printf ( "\tEliminação cancelada!\n" );
                    break;
                }
            }
        }

        i++;

        if ( i > 99 )
            printf ( "\n\n\t\tNIF não encontrado\n" );
    }

    fclose ( file );
    printf ( "\n\n\n\t\t\tPressione ENTER para Continuar->" );
    flush ();
    pressioneEnter();
    system ( "cls" );
}

void menu ( struct Funcionario funcionario[], int n ) {
    int op;

    do {
        system ( "COLOR 0F" ); //Menu
        printf ( "\n\n\t\t\t\t---> SISTEMA DE REGISTO E CONTROLE DE FUNCIONÁRIO \n\n" );
        printf ( "\n\t\t* 1 ------- INSERIR OS FUNCIONÁRIOS E ENVIA-LOS PARA O FICHEIRO ------------------------ *\n" );
        printf ( "\n\t\t* 2 ------- IMPRIMIR A LISTA DOS FUNCIONÁRIOS DO FICHEIRO ------------------------------ *\n" );
        printf ( "\n\t\t* 3 ------- IMPRIMIR OS FUNCIONÁRIOS POR CATEGORIA ------------------------------------- *\n" );
        printf ( "\n\t\t* 4 ------- GASTO DA UNIVERSIDADE COM OS FUNCIONÁRIOS ---------------------------------- *\n" );
        printf ( "\n\t\t* 5 ------- CALCULAR O SALÁRIO DE UM FUNCIONÁRIO X EM FUNÇÃO DO SEU SALÁRIO POR HORA --- *\n" );
        printf ( "\n\t\t* 6 ------- ORDENAR FUNCIONÁRIO NA ORDEM CRESCENTE ------------------------------------- *\n" );
        printf ( "\n\t\t* 7 ------- IMPRIMIR OS FUNCIONÁRIOS COM SALÁRIO MAIOR QUE 75000$ ---------------------- *\n" );
        printf ( "\n\t\t* 8 ------- ELIMINAR UM FUNCIONÁRIO A PARTIR DO Nº DO NIF ------------------------------ *\n" );
        printf ( "\n\t\t* 0 ------- Sair\n\n" );
        printf ( "\n\tEscolha uma opcao: " );
        scanf ( " %d", &op );
        printf ( "\n" );

        switch ( op ) {
        case 0:
            printf ( "\t\t\t\t\t\t\t\t\t\t-> Saindo... \n" );
            printf ( "\tPressione ENTER para Sair->" );
            flush ();
            pressioneEnter();
            system ( "cls" );
            break;

        case 1:
            system ( "cls" );
            IncerirFuncionario ( funcionario, n );
            break;

        case 2:
            system ( "cls" );
            ImprimirFuncionarios ( funcionario, n );
            break;

        case 6:
            system ( "cls" );
            OrdenarFuncionario ( funcionario, n );
            break;

        case 8:
            system ( "cls" );
            EliminarFuncionario ( funcionario, n );
            break;

        default:
            system ( "COLOR C0" );
            printf ( "\n\t\t\t\t*-*-*-*-- ERRO --> Numero INVALIDO!\n\n" );
            printf ( "\n\tPressione ENTER para Tentar Novamente->" );
            flush ();
            pressioneEnter();
            system ( "cls" );
        }
    } while ( op != 0 );

}
int main() {
    setlocale ( LC_ALL, "Portuguese" );
    struct Funcionario funcionario[100];
    int n;
    struct Funcionario* p = ( struct Funcionario * ) malloc ( sizeof ( struct Funcionario ) );

    if ( p == NULL ) {
        printf ( "\n\t ERRO MEMÓRIA INSUFICIENTE!\n" );
        exit ( 1 ); //Terminar o programa
    }

    system ( "COLOR F0" ); //Abertura do programa
    printf ( "\n\n\n\n\n\t\t\t....................................................................\n" );
    printf ( "\n\t\t\t\t----> SISTEMA DE REGISTO E CONTROLE DE FUNCIONÁRIO \n" );
    printf ( "\n\t\t\t.....................................................................\n\n\n\n\n" );
    printf ( "\n\t\t\t                                                                      UNICV \n\n" );
    printf ( "\n\tPressione ENTER 2 vezes para iniciar->" );
    flush ();
    pressioneEnter();
    system ( "cls" );
    menu ( funcionario, n );
    free ( p );
    return 0;

 

6 minutos atrás, arfneto disse:

Se se interessou por algo dessas "discussões meio paralelas" mas não compreendeu simplesmente como um ato de vingança "invada"  a discussão paralela e pergunte algo :)

Me interessou sim tinha algumas dúvidas no   flush ();  Obrigado

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

1 minuto atrás, arfneto disse:

Copiei seu programa. Pergunte algo objectivo e vou olhar logo mais

/*
1. Escreva uma função, que insira dados de N funcionários da Universidade Cabo Verde e envia-los para ficheiro como o nome 
funcionarios.txt (o programa deverá informar quantos funcionários deseja inserir no sistema?);
2. Escreva uma função, que imprima registos de todos os funcionários que se encontra no ficheiro com o nome funcionarios.txt, inserido 
anteriormente?
3. Escreva uma função, que imprima os funcionários por categoria. 
4. Escreva uma função, que permite calcular quanto gasta a universidade com os funcionários por categoria? 
5. Temos três tipos de categorias dos funcionários [Docente, Diretor e Técnico], sabendo que o funcionário que é Docente recebe 2500$ 
por cada hora, um Diretor recebe 3500$ por hora, e um Técnico recebe 1500$ por hora. Escreva uma função, que mostra o salário de 
um determinado funcionário dependendo do seu salário liquido por hora, sabendo que INPS é de 12%, IUR é de 20% e sindicato é de 
1%;
6. Escreva uma função, que ordena os funcionários na ordem crescentes e envia-los para o ficheiro com o nome 
ordenar_funcionarios.txt; 
7. Escreva uma função, que imprima todos os funcionários com salario maior que 75000$. 
8. Escreva uma função, que dado nº de NIF permite eliminar todas as informações desse funcionário.  
 */

O objectivo é fazer o programa que é capaz de fazer isso *_*

Link para o comentário
Compartilhar em outros sites

19 minutos atrás, Andrah disse:

O objectivo é fazer o programa que é capaz de fazer isso *_*

 

hey, reproduzir o enunciado não é uma pergunta objetiva.

 

Objetivo é você dizer em que ponto disso tem um problema agora...

 

Algo objetivo:

 

void EliminarFuncionario(struct Funcionario funcionario[], int n);

Esse trecho não está bom

trecho.png.a260febecb11f7662459d4fa6bfef97b.png

 

  • acabou de declarar i. Que acha que vai ter lá?
  • ler um char com o especificador %d é quase certo de cancelar seu programa
  • que 😈 é ativo? Não vi na declaração
  • se não vai fazer nada se file == NULL retorne apenas.
        if (file == NULL)
        {
            printf("\n-->Nao foi possivel abrir o fecheiro\n\n");
            return;
        }
    Pra que deslocar todo o seu programa pra direita? Dificultar a leitura?
     
  • Considere declarar um typedef para struct Funcionario... Para que digitar isso toda hora?
    typedef struct
    {
        char   categoria[20];
        int    Hora_Trabalhados;
        char   nome[20];
        char   NIF[20];
        float  salario;
    }  Funcionario;
    
    // Para não atrapalhar o bom funcionamento
    void menu(Funcionario funcionario[], int n);
  • Essa construção é comum, mas devia ser evitada:

image.png.424c79c293bba862c1b55f39c8d57a6c.png

 

Tudo isso é a mesma coisa. O prompt podia ser um parâmetro de pressioneEnter() não acha? Não seria original, já que o comum. E chamar flush(0 é supérfluo porque pressioneEnter() pode muito bem fazer isso. Limpar a tela e mostrar o menu novamente não sei... Precisaria ver o loop de execução de seu programa...

Algo assim
 

image.png.1c6fa0b8894e219da0e03599b29450ba.png

 

 

adicionado 16 minutos depois

Considere seu programa assim: não mudei nada exceto o mínimo para compilar e aquele if() de que falei

 

Coloquei um parametro em pressioneENTER()

e um int ativo em Funcionario e mudei para um typedef. Mas não mudei nada da lógica. Parece um pouco confuso ainda. Considere as coisas que perguntei. Talvez prefira prosseguir com o programa assim como abaixo. Repito não mudei nada. Mas compila e as funções estão em ordem

 


#include <conio.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

//Dados do funcionário
typedef struct
{
    int    ativo;
    char   categoria[20];
    int    Hora_Trabalhados;
    char   nome[20];
    char   NIF[20];
    float  salario;
}  Funcionario;

void EliminarFuncionario(Funcionario[], int);
void flush();
void InserirFuncionario(Funcionario[], int);
void menu(Funcionario[], int);
void OrdenarFuncionario(Funcionario*, int);
void pressioneEnter(const char*);


int main()
{
    setlocale(LC_ALL, "Portuguese");
    Funcionario funcionario[100];
    int n = 0;
    Funcionario* p = (Funcionario*) malloc(sizeof(Funcionario));

    if (p == NULL) {
        printf("\n\t ERRO MEMÓRIA INSUFICIENTE!\n");
        exit(1); //Terminar o programa
    }

    system("COLOR F0"); //Abertura do programa
    printf("\n\n\n\n\n\t\t\t....................................................................\n");
    printf("\n\t\t\t\t----> SISTEMA DE REGISTO E CONTROLE DE FUNCIONÁRIO \n");
    printf("\n\t\t\t.....................................................................\n\n\n\n\n");
    printf("\n\t\t\t                                                                      UNICV \n\n");
    printf("\n\tPressione ENTER 2 vezes para iniciar->");
    flush();
    pressioneEnter("");
    system("cls");
    menu(funcionario, n);
    free(p);
    return 0;
};  // main()


void EliminarFuncionario(Funcionario funcionario[], int n) {
    FILE* file;
    //Abre o arquivo novamente para leitura
    file = fopen("funcionarios.txt", "r+");
    if (file == NULL)
    {
        printf("\n-->Nao foi possivel abrir o fecheiro\n\n");
        return;
    }

    int i = 0;
    int nif;
    char resp;
    printf("\n\tInforme o NIF do funcionario a ser Eliminado: ");
    scanf(" %d", &nif);

    //while (funcionario[i].NIF == nif) so para compilar
    while (funcionario[i].NIF[0] == nif)
    {
        if (funcionario[i].ativo == 1)
        {
            printf("\n\tNome: %s", funcionario[i].nome);
            printf("\n\tNIF: %s", funcionario[i].NIF);
            printf("\n\tSalario: %.1f $00", funcionario[i].salario);
            printf("\n\tCategoria: %s", funcionario[i].categoria);
            printf("\n\tHoras de trabalho: %d horas", funcionario[i].Hora_Trabalhados);
            printf("\n\n----------------------------------------------------------\n");
        }

        printf("\n\tDeseja realmente eliminar o Funcionário? S/N:");
        scanf(" %c", &resp);

        if ((resp == 'S') || (resp == 's'))
        {
            funcionario[i].ativo = 0;
            printf("\n\tFuncionário eliminado com sucesso\n");
            break;
        }
        else
        {
            if ((resp == 'N') || (resp == 'n'))
            {
                printf("\tEliminação cancelada!\n");
                break;
            }
        }

        i++;

        if (i > 99)
            printf("\n\n\t\tNIF não encontrado\n");
    };  // while()
    fclose(file);
    pressioneEnter("\n\n\n\t\t\tPressione ENTER para Continuar->");
    system("cls");
};  // EliminarFuncionario()


void flush()
{
    int c;
    /*Lê todos os caracteres até encontrar '\n' ou EOF:*/
    while ((c = getchar()) != '\n' && c != EOF);
};  // flush()


void ImprimirFuncionarios(Funcionario funcionario[], int n) {
    FILE* file;

    file = fopen("C:\\Users\\alex\\Desktop\\ajuda\\funcionarios.txt", "r");

    if (file == NULL)
        printf("\n-->Nao foi possivel abrir o fecheiro\n\n");

    else {
        int i;
        printf("\n\n\n\t\t------- LISTA DOS FUNCIONÁRIOS ------\n\n");

        for (i = 0; i < n; i++) {
            system("COLOR 0F");
            fscanf(file, " %s", funcionario[i].nome);
            fscanf(file, " %s", funcionario[i].NIF);
            fscanf(file, " %f", &funcionario[i].salario);
            fscanf(file, " %s", funcionario[i].categoria);
            fscanf(file, " %d horas", &funcionario[i].Hora_Trabalhados);
            printf("\n\tNome: %s", funcionario[i].nome);
            printf("\n\tNIF: %s", funcionario[i].NIF);
            printf("\n\tSalario: %.1f $00", funcionario[i].salario);
            printf("\n\tCategoria: %s", funcionario[i].categoria);
            printf("\n\tHoras de trabalho: %d horas", funcionario[i].Hora_Trabalhados);
            printf("\n\n----------------------------------------------------------\n");
        }
    }

    pressioneEnter("");
    system("cls");
    fclose(file);
};  // ImprimirFuncionarios()


void InserirFuncionario(Funcionario funcionario[], int n) {
    system("COLOR 0F");
    FILE* file; // cria variável ponteiro para o arquivo
    file = fopen("funcionarios.txt", "w"); //abrindo o arquivo

    if (file == NULL) //testando se o arquivo foi realmente criado
        printf("\n-->Nao foi possivel abrir o fecheiro\n\n");
    else {
        printf("\n\n\n\n\tUNICV \n\n");
        printf("\n\n\n\t\tDigite o numero de Funcionarios que pretende registrar: ");
        scanf(" %i", &n);
        flush();
        system("cls");
        static int i = 0;
        int y = n + i;

        if (y > 99)
            menu(funcionario, n);

        printf("\n\n\n\t\t-------- INSCRIÇÃO DE FUNCIONÁRIO --------\n\n");
        fprintf(file, "\n\n\t----- LISTA DOS FUNCIONÁRIOS ----\n\n");
        fprintf(file, "\tNome      NIF 	  Salário     Categoria    Horas\n\n");

        for (; i < y; i++) {
            system("COLOR 0B");
            // para obter dados e armazenar no arquivo
            printf("\n\tDigite o nome do funcionário: ");
            scanf(" %s", funcionario[i].nome);
            flush();
            printf("\n\tDigite o NIF do funcionário: ");
            scanf(" %s", funcionario[i].NIF);
            printf("\n\tDigite o salario do funcionario: ");
            scanf(" %f", &funcionario[i].salario);
            flush();
            printf("\n\tDigite a categoria do funcionário: ");
            scanf(" %s", funcionario[i].categoria);
            printf("\n\tDigite a Hora trabalhados pelo funcionário: ");
            scanf(" %d", &funcionario[i].Hora_Trabalhados);
            printf("\n\n");
            //A Escrevendo no arquivo
            fprintf(file, "\t%s \t %s \t %.1f \t %s\t %d\n", funcionario[i].nome, funcionario[i].NIF, funcionario[i].salario, funcionario[i].categoria, funcionario[i].Hora_Trabalhados);
        }


        printf("\n\t\t-------------------------<3--------------------------\n");
        printf("\n\t Incritos com sucesso! \n\n\t Registado no fecheiro -> funcionarios.txt\n\n");
        pressioneEnter("\n\n\n\t\t\tPressione ENTER para Continuar->");
        system("cls");
        menu(funcionario, y);
    }

    fclose(file); // para fechar o arquivo
}


void menu(Funcionario funcionario[], int n) {
    int op;
    do {
        system("COLOR 0F"); //Menu
        printf("\n\n\t\t\t\t---> SISTEMA DE REGISTO E CONTROLE DE FUNCIONÁRIO \n\n");
        printf("\n\t\t* 1 ------- INSERIR OS FUNCIONÁRIOS E ENVIA-LOS PARA O FICHEIRO ------------------------ *\n");
        printf("\n\t\t* 2 ------- IMPRIMIR A LISTA DOS FUNCIONÁRIOS DO FICHEIRO ------------------------------ *\n");
        printf("\n\t\t* 3 ------- IMPRIMIR OS FUNCIONÁRIOS POR CATEGORIA ------------------------------------- *\n");
        printf("\n\t\t* 4 ------- GASTO DA UNIVERSIDADE COM OS FUNCIONÁRIOS ---------------------------------- *\n");
        printf("\n\t\t* 5 ------- CALCULAR O SALÁRIO DE UM FUNCIONÁRIO X EM FUNÇÃO DO SEU SALÁRIO POR HORA --- *\n");
        printf("\n\t\t* 6 ------- ORDENAR FUNCIONÁRIO NA ORDEM CRESCENTE ------------------------------------- *\n");
        printf("\n\t\t* 7 ------- IMPRIMIR OS FUNCIONÁRIOS COM SALÁRIO MAIOR QUE 75000$ ---------------------- *\n");
        printf("\n\t\t* 8 ------- ELIMINAR UM FUNCIONÁRIO A PARTIR DO Nº DO NIF ------------------------------ *\n");
        printf("\n\t\t* 0 ------- Sair\n\n");
        printf("\n\tEscolha uma opcao: ");
        scanf(" %d", &op);
        printf("\n");

        switch (op) {
        case 0:
            printf("\t\t\t\t\t\t\t\t\t\t-> Saindo... \n");
            pressioneEnter("\tPressione ENTER para Sair->");
            system("cls");
            break;

        case 1:
            system("cls");
            InserirFuncionario(funcionario, n);
            break;

        case 2:
            system("cls");
            ImprimirFuncionarios(funcionario, n);
            break;

        case 6:
            system("cls");
            OrdenarFuncionario(funcionario, n);
            break;

        case 8:
            system("cls");
            EliminarFuncionario(funcionario, n);
            break;

        default:
            system("COLOR C0");
            printf("\n\t\t\t\t*-*-*-*-- ERRO --> Numero INVALIDO!\n\n");
            printf("\n\tPressione ENTER para Tentar Novamente->");
            flush();
            pressioneEnter("");
            system("cls");
        }
    } while (op != 0);
}


void OrdenarFuncionario(Funcionario* funcionario, int n) {

    int i, j;
    Funcionario aux;

    for (i = 1; i < n; i++) {
        aux = funcionario[i];

        for (j = i; (j > 0) && (aux.salario < funcionario[j - 1].salario); j--) {
            funcionario[j] = funcionario[j - 1];
            funcionario[j] = aux;
        }

    }

    printf("\n\n\n\t------- LISTA DOS FUNCIONÁRIOS POR ORDEM CRESCENTE ------\n\n");

    for (i = 0; i < n; i++) {

        printf("\n\tNome: %s", funcionario[i].nome);
        printf("\n\tNIF: %s", funcionario[i].NIF);
        printf("\n\tSalario: %.1f $00", funcionario[i].salario);
        printf("\n\tCategoria: %s", funcionario[i].categoria);
        printf("\n\tHoras de trabalho: %d horas", funcionario[i].Hora_Trabalhados);
        printf("\n\n----------------------------------------------------------\n");

    }

    printf("\n\n\n\t\t\tPressione ENTER para Continuar->");
    flush();
    pressioneEnter("");
    system("cls");
}


void pressioneEnter(const char* prompt)
{
    char c;
    if(prompt != NULL) printf("%s", prompt);
    do {
        c = getc(stdin);
    } while (c != 13);
};  // pressioneEnter()

// fim

 

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

1 hora atrás, arfneto disse:

Algo objetivo:

Algo objetivo não sei dizer mas vou tentar resolver os outros e postar aqui se ta algo errado me corrija pode ser?

1 hora atrás, arfneto disse:

O prompt podia ser um parâmetro de pressioneEnter() não acha?

Acho sim Obrigado mesmo :) 

1 hora atrás, arfneto disse:

Repito não mudei nada. Mas compila e as funções estão em ordem

Ta bom Obrigado na mesma! 

Link para o comentário
Compartilhar em outros sites

Neste tipo de programa eu considero que pode haver dois tipos de arquivos onde devem ser escritos dados/informações: Um tipo seria o tipo "relatório" que contém algo para ser lido por um humano, logo deve estar formatado e organizado de forma a facilitar o entendimento pela pessoa que vai ler. O outro tipo seria o tipo "banco de dados" que só será lido pelo programa, logo não há necessidade de formatação pois nenhuma pessoa deve ler este tipo de arquivo diretamente, o que importa para este tipo de arquivo é facilitar que o programa armazene e recupere os dados do arquivo, logo quão mais simples e direto for melhor, e não há necessidade de "embelezar".

 

Digo isso porque tenho perguntas sobre esse enunciado e como você implementou...

 

Veja: Digamos que use o programa 1 vez e cadastre alguns funcionários, se o programa for finalizado quando ele for aberto novamente os funcionários cadastrados anteriormente persistem, ou deve recomeçar a cadastrar do zero toda vez?

 

Acredito que deva recuperar os dados salvos ao abrir o programa, certo?

 

Então isso me diz que o arquivo funcionarios.txt deveria fazer o papel de "banco de dados" e armazenar a lista de funcionários da forma que for mais fácil de acessar e recuperar os dados.

 

 Na função IncerirFuncionario (obs: inserir se escreve com s não com c ) por que você está formatando o texto dentro do arquivo funcionarios.txt?

        fprintf ( file, "\n\n\t----- LISTA DOS FUNCIONÁRIOS ----\n\n" );
        fprintf ( file, "\tNome      NIF 	  Salário     Categoria    Horas\n\n" );

E

            fprintf ( file, "\t%s \t %s \t %.1f \t %s\t %d\n", funcionario[i].nome, funcionario[i].NIF, funcionario[i].salario, funcionario[i].categoria, funcionario[i].Hora_Trabalhados );

 

Ou seja, para que está incluindo os títulos e as tabulações para deixar "bonito" dentro do arquivo? Isso é requisito ou você adicionou por conta própria?

 

Por que se não for requisito isso só vai complicar para recuperar os dados do arquivo para a memória com o fscanf, pois note que primeiro vai ter que ignorar as 2 primeiras linhas, que contém os títulos, para depois começar a ler os dados separados por tabulação.

 

Claro, não é muito difícil fazer isso, mas a questão é se existe a necessidade quando pode fazer algo mais simples que tornaria fazer o código mais fácil e daria mais opções. Por exemplo, poderia separar cada dado do funcionário 1 cada linha (ou seja um '\n' separa cada dado do funcionário), permitindo usar fgets para ler as strings. (Ou até usar o meu método favorito que é, ao invés de fprintf() e fscanf(), usar fwrite() e fread() para escrever e ler do arquivo a struct inteira contendo todos os dados do funcionário de uma vez.)

 

O modo que eu faria esse código (se for usar o método com fprintf e fscanf) a primeira linha do arquivo funcionarios.txt teria a quantidade total de funcionários já armazenadas no arquivo, seguido imediatamente pelos dados de cada funcionário, para facilitar a fazer a função que recupera os dados para a memória na próxima execução do programa.

 

 

Obs: De acordo com a minha distinção de tipos de arquivos o arquivo ordenar_funcionarios.txt poderia ser tanto do tipo "relatório" quanto do tipo "banco de dados", mas como não há nenhuma outra indicação eu usaria como um "relatório" formatando para poder ser lido pelo usuário diretamente.

 

  • Curtir 1
  • Amei 1
Link para o comentário
Compartilhar em outros sites

19 minutos atrás, isrnick disse:

Acredito que deva recuperar os dados salvos ao abrir o programa, certo?

Certo!

19 minutos atrás, isrnick disse:

Na função IncerirFuncionario (obs: inserir se escreve com s não com c ) por que você está formatando o texto dentro do arquivo funcionarios.txt?

Obrigado, para que o usuário possa utilizar o arquivo de pois 

sem precisar escrever tudo de novo 

19 minutos atrás, isrnick disse:

Isso é requisito ou você adicionou por conta própria?

Por conta própria é para deixar mais "bonito" kkkk 

19 minutos atrás, isrnick disse:

(Ou até usar o meu método favorito que é, ao invés de fprintf() e fscanf(), usar fwrite() e fread() para escrever e ler do arquivo a struct inteira contendo todos os dados do funcionário de uma vez.)

Sim poderia fazer assim mas só que o nosso professor não nos encimou e ele não aceita assim porque tem que parecer os dados no arquivo não em binário

tinha feito assim 

/bibliotecas
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include <conio.h>
#include <time.h>




//Dados do funcionário
struct Funcionario {
    char nome[20];
    char NIF[20];
    char categoria;
    float salario;
    int diasTrabalhados;
    //Codigo que verifica se o funcionário está ativo no sistema
    int ativo;
};

void pressioneEnter() {
    char c;
    do {
        c = getch();
    } while (c != 13);
}

//Funções a - z
struct Funcionario *criarFuncionario();


void cadastrarFuncionario(struct Funcionario *funcionario, FILE *file) {
    printf("\n-------Cadastro de funcionário--------\n");
    printf("\nInforme o nome do funcionário: ");
    scanf(" %s", funcionario->nome);
    printf("\nInforme o NIF do funcionário: ");
    scanf(" %i", funcionario->NIF);
    printf("\nInforme o salario do funcionario: ");
    scanf("%f", &funcionario->salario);
    printf("\nInforme os dias trabalhados pelo funcionário: ");
    scanf("%d", &funcionario->diasTrabalhados);
    printf("\nInforme a categoria do funcionário: ");
    scanf(" %c", &funcionario->categoria);
    //Ativo no sistema
    funcionario->ativo = 1;
    printf("\nFuncionário inserido com sucesso!");
    fwrite(funcionario, 1, sizeof(struct Funcionario), file);
}

float contarGastos(struct Funcionario *funcionario, FILE *file) {
    float custo = 0;
    while (fread(funcionario, 1, sizeof(struct Funcionario), file)) {
        custo += funcionario->salario;
    }
    return custo;
}

struct Funcionario *criarFuncionario() {
    return (struct Funcionario *)malloc(sizeof(struct Funcionario));
}

void deletarFuncionario(struct Funcionario *funcionario, FILE *file, char *nif) {
    rewind(file);
    while (fread(funcionario, 1, sizeof(struct Funcionario), file)) {
        if (strcmp(funcionario->NIF, nif) == 0 && funcionario->ativo == 1) {
            break;
        }
    }
    fseek(file, -sizeof(struct Funcionario), SEEK_CUR);
    funcionario->ativo = 0;
    fwrite(funcionario, 1, sizeof(struct Funcionario), file);
    printf("\nFuncionario excluido com sucesso!");
}

void listarFuncionarios(struct Funcionario *funcionario, FILE *file) {
    printf("\n------- Listando funcionários ------\n");
    while (fread(funcionario, 1, sizeof(struct Funcionario), file)) {
        if (funcionario->ativo == 1) {
            printf("\nNIF: %s", funcionario->NIF);
            printf("\nNome: %s", funcionario->nome);
            printf("\nCategoria: %c", funcionario->categoria);
            printf("\nSalario: (sua moeda)%.2f", funcionario->salario);
            printf("\nDias trabalhados por semana: %d", funcionario->diasTrabalhados);
            printf("\n----------------------------------------------------------\n");
        }
    }
}

void listarFuncionariosCategoria(struct Funcionario *funcionario, FILE *file) {
    char categoria;
    printf("\nInforme a categoria desejada: ");
    scanf(" %c", &categoria);
    while (fread(funcionario, 1, sizeof(struct Funcionario), file)) {
        if (funcionario->categoria == categoria && funcionario->ativo == 1) {
            printf("\nNIF: %s", funcionario->NIF);
            printf("\nNome: %s", funcionario->nome);
            printf("\nCategoria: %c", funcionario->categoria);
            printf("\nSalario: (sua moeda)%.2f", funcionario->salario);
            printf("\nDias trabalhados por semana: %d", funcionario->diasTrabalhados);
            printf("\n----------------------------------------------------------\n");
        }
    }
}

void menu(struct Funcionario *funcionario) {
    FILE *file;
    int op;
    char nif[20];
    do {
        system("COLOR 0F");  //Menu
        printf("\n\n\n\t\t\t\t---> SISTEMA DE REGISTO E CONTROLE DE FUNCIONARIO \n\n");
        printf("\n\t\t* 1 ------- INSERIR OS FUNCIONARIOS E ENVIA-LOS PARA O FICHEIRO ------------------------ *\n");
        printf("\n\t\t* 2 ------- IMPRIMIR A LISTA DOS FUNCIONARIOS DO FICHEIRO ------------------------------ *\n");
        printf("\n\t\t* 3 ------- IMPRIMIR OS FUNCIONARIOS POR CATEGORIA ------------------------------------- *\n");
        printf("\n\t\t* 4 ------- GASTO DA UNIVERSIDADE COM OS FUNCIONARIOS ---------------------------------- *\n");
        printf("\n\t\t* 5 ------- CALCULAR O SALARIO DE UM FUNCIONARIO X EM FUNCAO DO SEU SALARIO POR HORA --- *\n");
        printf("\n\t\t* 6 ------- ORDENAR FUNCIONARIO NA ORDEM CRESCENTE ------------------------------------- *\n");
        printf("\n\t\t* 7 ------- IMPRIMIR OS FUNCIONARIOS COM SALARIO MAIOR QUE 75000$ ---------------------- *\n");
        printf("\n\t\t* 8 ------- ELIMINAR UM FUNCIONARIO A PARTIR DO N DO NIF ------------------------------- *\n");
        printf("\n\t\t* 0 ------- Sair\n\n\n");
        printf("\n\tEscolha uma opcao: ");
        scanf("%d",&op);
        printf("\n");
        switch (op) {
        case 0:
            printf("\nSaindo...\n");
            break;
        case 1:
            file = fopen("funcionarios.txt", "ab");
            cadastrarFuncionario(funcionario, file);
            fclose(file);
            break;
        case 2:
            file = fopen("funcionarios.txt", "rb");
            listarFuncionarios(funcionario, file);
            break;
        case 3:
            file = fopen("funcionarios.txt", "rb");
            listarFuncionariosCategoria(funcionario, file);
            break;
        case 4:
            file = fopen("funcionarios.txt", "rb");
            printf("\nO total gasto com salarios eh: (sua moeda)%.2f\n", contarGastos(funcionario, file));
            break;
        case 8:
            file = fopen("funcionarios.txt", "rb+");
            printf("\nInforme o NIF do funcionario a ser deletado: ");
            scanf(" %s", nif);
            deletarFuncionario(funcionario, file, nif);
            fclose(file);
            break;
        default:
            system("COLOR C0");
            printf("\n\t\t\t\t*-*-*-*-- ERRO --> Numero INVALIDO!\n\n");
            printf ("\n\tPressione ENTER para Tentar Novamente->");
            fflush(stdin);
            pressioneEnter();
            system("cls");
        }
    } while (op != 0);
}

//Main
int main() {
    setlocale(LC_ALL, "Portuguese");
    system("COLOR F0"); //Abertura do programa
    printf("\n\n\n\n\n\t\t\t....................................................................\n");
    printf("\n\t\t\t\t----> SISTEMA DE REGISTO E CONTROLE DE FUNCIONARIO \n");
    printf("\n\t\t\t.....................................................................\n\n\n\n");
    printf ("\n\tPressione ENTER para iniciar->");
    fflush(stdin);
    pressioneEnter();
    system("cls");
    struct Funcionario *funcionario;
    funcionario = criarFuncionario();
    menu(funcionario);
}

  

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

10 minutos atrás, Andrah disse:

Sim poderia fazer assim mas só que o nosso professor não nos encimou e ele não aceita assim porque tem que parecer os dados no arquivo não em binário

tinha feito assim 

 

Entendi.

Bom, dá pra fazer com fprintf e fscanf. 

 

 

8 minutos atrás, Andrah disse:

Por conta própria é para deixar mais "bonito" kkkk 

 

8 minutos atrás, Andrah disse:

Obrigado, para que o usuário possa utilizar o arquivo de pois 

sem precisar escrever tudo de novo 

 

Não entendi porque o usuário precisaria escrever algo mais de uma vez se não estiver formatado bonitinho.

 

De qualquer maneira se pretende manter assim então tem que corrigir a função ImprimirFuncionarios, pois do modo que está agora ele vai tentar dar fscanf nas 2 linhas com títulos como se fossem dados dos funcionários, e bagunçar toda a leitura, então tem que fazer fscanf ou fgets específico para ler essas 2 linhas que não contém dados.

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

2 minutos atrás, isrnick disse:

De qualquer maneira se pretende manter assim então tem que corrigir a função ImprimirFuncionarios, pois do modo que está agora ele vai tentar dar fscanf nas 2 linhas com títulos como se fossem dados dos funcionários, e bagunçar toda a leitura, então tem que fazer fscanf ou fgets específico para ler essas 2 linhas que não contém dados.

ta bom vou corrigir obrigado 

ta me ajudando muito 

Link para o comentário
Compartilhar em outros sites

1 minuto atrás, arfneto disse:

Você leu o código reordenado? Entendeu as diferenças? O que é o tal campo "ativo"? Viu que eu inseri na estrutura? Vai usar essa estrutura? Entendeu as notas sobre pressioneEnter( e flush()?

sim obrigado mas tem um probleminha 

não ta saindo daqui

Capturar.PNG

Link para o comentário
Compartilhar em outros sites

Agora isto:

        static int i = 0;
        int y = n + i;

        if ( y > 99 )
            menu ( funcionario, n );

E isto:

        menu(funcionario, y);

Dentro da função InserirFuncionario são aberrações que não deveriam existir. 😆

 

Isso está criando recursividade desnecessária e descontrolada, e pior ainda, em ambos os casos chama a função menu sem fechar o arquivo que foi aberto com fopen, aí de dentro do menu pode chamar novamente a função InserirFuncionario, que vai tentar abrir com fopen novamente o arquivo que já está aberto!

 

Mude a lógica para retornar o valor de n seja como retorno da função (muda o tipo da função de void para int), ou então muda a variável n para um ponteiro para que alterações dentro da função também mudem o valor fora dela, ou então faz pedir pra digitar o número de funcionários a serem inseridos fora da InserirFuncionario, na própria menu(), e a InserirFuncionario apenas retornar se teve sucesso ou se falhou (e soma ao total se teve sucesso), em fim tem muitos métodos melhores.

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

5 minutos atrás, isrnick disse:

Mude a lógica para retornar o valor de n seja como retorno da função (muda o tipo da função de void para int), ou então muda a variável n para um ponteiro para que alterações dentro da função também mudem o valor fora dela, ou então faz pedir pra digitar o número de funcionários a serem inseridos fora da InserirFuncionario, na própria menu(), e a InserirFuncionario apenas retornar se teve sucesso ou se falhou (e soma ao total se teve sucesso), em fim tem muitos métodos melhores.

Obrigado, vou tentar fazer de outro jeito amanhã e vou postar aqui se tiver alguma coisa errada  me avisa por favor 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

O mais interessante seria fazer uma competição para ver quem tem a razão! kkkk

Então quem conseguir fazer o programa como o enunciado pede ( com todos os cases)  ganha!

O que acham kkkkk

Assim todos SAIRIAM FELIZES principalmente EU :) 

Link para o comentário
Compartilhar em outros sites

acho que resolver um problema é uma coisa muito boa, mas querer saber qual a melhor solução para  um problema é querer ser o melhor. Creio que com o passar do tempo os sistemas vão mudando ("evoluindo") e muitos desses problemas vão desaparecer. Afinal nem todo mundo é perfeito e os gênios que criaram falharam. Buffer é um assunto complexo e existem diversos tipos.

  • Amei 1
Link para o comentário
Compartilhar em outros sites

1 hora atrás, Andrah disse:

sim obrigado mas tem um probleminha 

não ta saindo daqui

 

Não tentei ler o programa, mas qual a ideia de ENTER 2 VEZES? 

image.png.1a4f002b11a0819089cd783e1402f41a.png

 

Se está tentando isso com uma achamada a pressione ENTER não vai rolar. 

Sua ideia do menu esta confusa sem necessidade. 

Talvez pudesse simplesmente limpar a tela ao entrar no menu uma unica vez.

Ler a opção, tratar, e voltar. Só isso.

 

adicionado 46 minutos depois
1 hora atrás, vangodp disse:

você ta de sacanagem né? Não mostra o que vei...? É que acaso tem que mostrar algo? Funciona, é brilhante pela simplicidade. Por muito que entre o enter este buffer não da erros, é funcional, por muito que que a você não lhe agrade ta aí mais uma forma de ler desde o buffer

 

É estranho dizer que sua própria ideia é brilhante. O "buffer" de que está lendo é uma variável do seu programa. Você já leu do stream e, ao invés de usar fscanf() que leria do buffer do stream, você usa sscanf() que e lê de uma variável do seu programa que você sabiamente chamou de buffer. 

 

image.png.ba3aff31652fc1e3bbaa6d2bb33ac1ec.png

 

1 hora atrás, vangodp disse:

Mas para que preciso disso??? Ja não viu o 10, não ficou satisfeito???? Que precisa mais?? WTF

 

Para que eu preciso disso:

 

Eu te mostrei um exemplo. Mas vou repetir o caso mais simples: imagine que você não quer ler enquanto não tenha nada pra ler. Entenda isso. É importante. Essencial às vezes se seu programa NÃO FOR MULTI-THREAD. 

 

O caso mais simples: seu programa está rodando e é um jogo de console. A tela esta rodando algum tipo de animação. O usuário tem uns comandos, tipo movimento e tiro. E você pode ler os clássicos E S D X para os movimentos e ESPAÇO para atirar. 

 

Se você escrever um fread(), um scanf(), um getc(), um fgets() o programa vai PARAR pra ler o comando até o cara digitar algo. Você só quer ler o comando depois que souber que o cara digitou. Entenda isso. Se não entendeu escreva explicando onde está a dúvida desta vez. É um conceito importante. Você não pode parar a execução e ficar esperando. Também não pode ler para o seu "brilhante" buffer o que ainda não foi digitado. Para isso precisa da colaboração do sistema operacional. No windows pode usar a rotina que te mostrei. No Unix usa algo como ioctl() e faz algo similar. Eu escrevi soluções assim para Unix muitas vezes, mas não me lembro dos detalhes, mas tem algo na estrutura dos buffer do terminal que dava essa informação de que tem algo a ser lido. Sinceramente não me lembro. 

Não adianta nada ler para a sua variável buffer

 

1 hora atrás, vangodp disse:

Não... não tem o mesmo problema... funciona perfeitamente, e você sabe. É uma de tantas mais que existe, toma ou deixa

1 hora atrás, vangodp disse:

E que importa??

 

Espero que tenha entendido agora. São coisas que acontecem em tempo real. Não dá pra ler antes no buffer que está dentro do seu programa porque ninguém digitou ainda. Seu programa segue um loop de execução e se o usuário digitou algo você vai lá e lê. Não pode ler antes de ele ter digitado. Mas às vezes não pode simplesmente escrever um scanf() e ficar esperando...

 

1 hora atrás, vangodp disse:

Vei... vai catar coquinho com os multi-thread. Onde você ta vendo multi-thread aqui? É vontade de causar polêmica n é?

 

Seu tom parece não estar sendo de muita cortesia. Vou explicar isso de novo também: SE FOSSE MULTI-THREAD seu programa poderia ter um loop de execução e outro de leitura e aí o de leitura poderia ficar parado. Entendeu agora? Como o programa, o nosso exemplo aqui,  é um programa comum com uma sequência de execução só, sabe o que acontece se você chama um read: o programa para.

 

1 hora atrás, vangodp disse:

Arfnet, conforme sua grande experiência... Qual a solução mais adequada ao problema do buffer??? Oh gran arf! Responda só isso. Quero ver... Não! Acho que a essa altura todos queremos ver sua solução perfeita para o tema do LIXO no buffer de entrada

 

Talvez possa mudar o tom. Não tenho uma solução perfeita. E já te disse que não se trata de lixo. Não sei se existe tal coisa de solução perfeita. Eu te mostrei as DUAS opções que se usa na prática e até com detalhe: Ler caracteres via getc() ou linhas via gets() e tratar em seu programa. Até citei o que o runtime faz montando o vetor de argv antes de acionar seu programa em C. E quando precisar usar em Windows PeekConsoleInput() para ver se tem algo pra ler e só ler se tiver. E no Linux/Mac ver a outra solução de que falei e não me lembro. E te falei da existência de ungetc() em todas as plataformas. 

 

Já que estou escrevendo, vou te dar um exemplo de que me lembrei agora. Nos '90 eu trabalhava em um sistema grande em UNIX para automação bancária e tinha uma situação em que máquinas especiais eram ligadas como terminais do Unix e o sistema era controlado por dois terminais de uso dos operadores das máquinas. Sempre que a máquina terminava um certo processo uma mensagem indicativa aparecia na tela e o operador tinha que ir até a máquina retirar um lote de documentos e voltar ao terminal para autorizar o reinício. 
 

Durante meses o pessoal pedia uma maneira de escolher um tempo para reinício e voltar sózinho a ler A MENOS que eles usassem algum comando, ao invés de sempre parar e eles terem que voltar ao terminal nem que fosse para teclar um ENTER. Já imaginou o cenário certo? O sistema era escrito em COBOL e minha solução foi escrever um read em C que substituía a leitura do COBOL e depois do tempo que cada operador podia programar em seu turno voltava a acionar as máquinas a menos que o operador digitasse um comando. Entendeu a diferença? Só lia quando ele tinha digitado algo. 

 

1 hora atrás, vangodp disse:

Então ganha o arf... acho que ele sempre tem razão

 

Sinto por isso. Se não entendeu mesmo o que expliquei ou ainda acha que quero criar polêmica. Eu te mostrei vários exemplos. 

 

 

 

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!