Read from file and use read parts to call functions

Asked

Viewed 108 times

1

I have a file that contains calls to functions present in my code. Some examples of functions are criar(), inserir(elemento, conjunto), listar(conjunto) where the arguments are integers passed to the function. These functions must be called through the arquivo.txt that will contain, for example:

criar() inserir(1,0) listar(0)

To read the file, I used the following function:

void leArquivo(){
FILE *arq;

    if((arq = fopen("arquivo.txt", "r")) == NULL)
            printf("Erro ao abrir o arquivo.\n");

    char buffer[100];
    char *p;

    while (fscanf (arq, "%s\n", buffer) != EOF) {
            p = buffer;
            printf("%s\n", p);    
    }    
    fclose (arq);
}

However, this only prints the "name" of the function itself, and does not call it. For example, if in the file the function is criar(), he printa criar() and not the return of the create function. I found that, as printf("%d", criar()); returns the function value, printf("%d\n", p); would return the same, but not.

I thought I’d use the function strcmp() to be able to compare if the names are equal and hence call the function, and I succeeded in functions without arguments, but I do not know how to do for functions like inserir(elemento, conjunto), where it is not possible to "predict" the arguments. Any suggestions on how to call these functions from reading the file?

  • 3

    Show your code in a way that can be analyzed better what you are doing. Leave it in a state that can be compiled and executed as far as you can. But I can already say that you are far from the result. You will have to analyze the string and decide what to do. That is, you will have to do some form of parser. It’s not that simple.

  • It’s just that I thought what the functions themselves did would make no difference, since they all return only integers that must be displayed. The problem is actually calling them from the file. :(

  • 1

    The idea of strcmp is the most common way for these things, if the language of functions is not too complex. Compares the string to an if (or switch) and true case calls the function (doing this one by one). What can help is to change the syntax, leaving the functions of the same size and with parameters in the same order (but there goes the concrete case).

1 answer

0

See if the function below fits your need:

this code snippet will read the text file and look for the function in a structure already defined and execute the command if it exists.

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

#include <readline/readline.h>
#include <readline/history.h>

typedef void cmd_function_t(char *);

//estrutura dos comandos
typedef struct {
    char *name;
    cmd_function_t *func;
} command_t;

static void execute_command(char *line);
static command_t *find_command(char *name);

//comandos para rodar
static void comando1(char *arg);
static void comando2(char *arg);
static void comando3(char *arg);
static void comando4(char *arg);

command_t commands[] = {
        { "comando1", comando1 },
        { "comando2", comando2 },
        { "comando3", comando3 },
        { "comando4", comando4 },
};

static command_t *find_command(char *name) {
    register int i;
    size_t namelen;

    if ((name == NULL) || (*name == '\0'))
        return ((command_t *) NULL);

    namelen = strlen(name);
    for (i = 0; commands[i].name; i++) {
        if (strncmp(name, commands[i].name, namelen - 1) == 0) {
            /* make sure the match is unique */
            if ((commands[i + 1].name)
                    && (strncmp(name, commands[i + 1].name, namelen) == 0))
                return ((command_t *) NULL);
            else
                return (&commands[i]);
        }
    }

    return ((command_t *) NULL);
}

//função que pega o texto encontrado e executa
static void execute_command(char *line) {

    register int i;
    command_t *command;
    char *word;

    /* Isolate the command word. */
    i = 0;
    while (line[i] && whitespace(line[i]))
        i++;
    word = line + i;

    while (line[i] && !whitespace(line[i]))
        i++;

    if (line[i])
        line[i++] = '\0';

    command = find_command(word);

    if (!command) {
        return;
    }

    /* Get argument to command, if any. */
    while (whitespace(line[i]))
        i++;

    word = line + i;

    /* invoke the command function. */
    (*command->func)(word);
}

static void comando1(char *arg) {

    printf("\nExecutando o Comando 1\n");
    fflush(NULL);
}

static void comando2(char *arg) {

    printf("\nExecutando o Comando 2\n");
    fflush(NULL);
}

static void comando3(char *arg) {

    printf("\nExecutando o Comando 3\n");
    fflush(NULL);
}

static void comando4(char *arg) {

    printf("\nExecutando o Comando 4\n");
    fflush(NULL);
}

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

    FILE * fp;
    char * line = NULL;
    size_t len = 0;
    ssize_t read;
    char *cmd;

    fp = fopen("arquivo.txt", "r");
    if (fp == NULL)
        exit(EXIT_FAILURE);

    if ((read = getline(&line, &len, fp)) != -1) {
        if (line == NULL) {
            printf("Sem comando\n");
        }

        cmd = line;

        if (*cmd) {
            execute_command(cmd);
        }

    }

    fclose(fp);
    if (line)
        free(line);
    exit(EXIT_SUCCESS);

}
  • I haven’t tested your code, but I believe it works (because the AP problem is somewhat trivial). But to earn my +1, you would need to at least explain details of how your code works. In my view, the idea of Sopt is also to spread knowledge, not just to share code. : ) It would be important for the PA to understand what happens, and especially to have its main doubt (because printf of a text is not the same thing as calling a function? ) answered.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.