@tofibos215

Как сохранять значение переменных в input stream?

Здравствуйте, хочу реализовать такую вещь.
Вводить в input stream различные переменные variable = 1

и потом выводить её RRINT variable (выводит 1)

Как это можно реализовать?

Любому совету буду рад. Если дадите статьи по теме, то буду благодарен.
  • Вопрос задан
  • 112 просмотров
Решения вопроса 1
includedlibrary
@includedlibrary
Я написал простой пример. Для объявления переменной нужно ввести строку символов формата: varname = number. Для вывода значения переменной - строку формата: print varname. Файл htable.c с реализацией хэш-таблицы в вопрос не влез, если его содержимое будет нужным могу сделать гисту.

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "htable.h"

typedef struct {
    uint32_t hash;
    char    *var;
    int      val;
} varnode_t;

uint32_t varnode_hash(hnode_t *_node) {
    varnode_t *node = (varnode_t*)_node;
    return default_hash_func((uint8_t*)node->var, strlen(node->var));
}

bool varnode_keyeq(hnode_t *_node1, hnode_t *_node2) {
    varnode_t *node1 = (varnode_t*)_node1;
    varnode_t *node2 = (varnode_t*)_node2;
    return !strcmp(node1->var, node2->var);
}

void varnode_free(hnode_t *_node) {
    varnode_t *node = (varnode_t*)_node;
    free(node->var);
}

typedef struct {
    char   *input;
    size_t input_size;
    size_t offset;
    char *var;
    int   val;
} parser_t;

void rollback(parser_t *p) {
    if(p->var) {
        free(p->var);
        p->var = NULL;
    }
}

bool get_var(parser_t *p) {
    size_t init_offset = p->offset;
    while(p->offset++ < p->input_size) {
        if(p->input[p->offset] == ' ') {
            p->input[p->offset] = '\0';
            p->var = strdup(p->input + init_offset);
            if(!p->var) {
                perror("failed to allocate memory");
                return false;
            }
            p->input[p->offset] = ' ';
            while(p->input[p->offset] == ' ' && p->offset < p->input_size)
                p->offset++;
            return true;
        } else if(p->input[p->offset] < 'a' || p->input[p->offset] > 'z') {
            fputs("error: non-letter character in variable name\n", stderr);
            return false;
        }
    }
    return false;
}

bool check_eq(parser_t *p) {
    if(p->input[p->offset++] != '=') {
        fputs("error: expected '=' sign\n", stderr);
        return false;
    }
    while(p->input[p->offset] == ' ' && p->offset < p->input_size)
        p->offset++;
    return true;
}

bool get_val(parser_t *p) {
    if(p->input[p->offset] == '-')
        p->offset++;
    size_t init_offset = p->offset;
    while(p->offset < p->input_size) {
        if(p->input[p->offset] < '0' || p->input[p->offset] > '9') {
            fputs("error: non-digital character in expression\n", stderr);
            return false;
        }
        p->offset++;
    }

    p->val = atoi(p->input + init_offset);

    return true;
}

int main() {
    char buf[256];
    parser_t parser = {
        .input = buf,
        .var = NULL
    };

    htable_t *vars = htable_create(sizeof(varnode_t), 8,
                                   varnode_hash,
                                   varnode_keyeq,
                                   varnode_free);
    if(!vars)
        return 2;

    while(fgets(buf, sizeof(buf)-1, stdin)) {
        parser.offset = 0;
        parser.input_size = strlen(buf);

        if(buf[parser.input_size-1] == '\n') {
            buf[parser.input_size-1] = '\0';
            parser.input_size--;
        }

        if(strstr(buf, "print")) {
            size_t off = 5;
            while(buf[off] == ' ' && off < parser.input_size)
                off++;

            varnode_t findvar = {
                .var = buf + off
            };

            varnode_t *var = (varnode_t*)htable_lookup(vars, (hnode_t*)&findvar);
            if(!var) {
                fprintf(stderr, "error: undefined variable %s\n", findvar.var);
                continue;
            }

            printf("%s = %d\n", var->var, var->val);
            continue;
        }

        if(!get_var(&parser)  ||
           !check_eq(&parser) ||
           !get_val(&parser)) {
            rollback(&parser);
            continue;
        }

        varnode_t *newvar = malloc(sizeof(varnode_t));
        if(!newvar) {
            perror("failed to allocate memory");
            rollback(&parser);
            continue;
        }

        newvar->var = parser.var;
        newvar->val = parser.val;

        if(!htable_insert(vars, (hnode_t*)newvar)) {
            fprintf(stderr, "error: failed to insert var %s\n", newvar->var);
            rollback(&parser);
            free(newvar);
        }
    }

    htable_free(vars);
}


htable.h

#pragma once

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

typedef struct {
    uint32_t hash;
} hnode_t;

typedef uint32_t (*htable_hash_func)(hnode_t*);
typedef bool (*htable_keyeq_func)(hnode_t*, hnode_t*);
typedef void (*htable_free_func)(hnode_t*);
typedef struct {
    hnode_t **nodes;
    size_t  node_size;
    size_t  num_nodes;
    size_t  max_nodes;
    int     size_ind;

    htable_hash_func  hash_func;
    htable_keyeq_func keyeq_func;
    htable_free_func  free_func;
} htable_t;

uint32_t default_hash_func(const uint8_t *key, size_t length);

htable_t* htable_create(size_t node_size, size_t max_nodes, htable_hash_func hash_func, htable_keyeq_func keyeq_func, htable_free_func free_func);
bool htable_insert(htable_t *htable, hnode_t *node);
hnode_t* htable_lookup(htable_t *htable, hnode_t *node);
void htable_free(htable_t *htable);

Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы