You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自制C语言解释器无法存储读取变量问题求助

问题排查与修复:自定义语言解释器变量存储失败

问题根源

你的测试脚本中console:read->"Enter your name: "->name这类命令,当前代码仅处理了读取用户输入的环节,完全未实现将输入内容存储到指定变量name的逻辑;同时fgets读取的输入会包含换行符,若不清理会导致变量值带多余格式。

具体问题点:

  • interpretCommand的console:read->分支里,读取userInput后无后续处理,既没提取命令末尾的变量名,也没将输入写入变量数组。
  • 原代码的变量赋值逻辑仅在「非console命令」的else分支触发,但你的read命令属于console命令范畴,因此这部分逻辑不会执行。

修复步骤

  1. 在console:read->分支中提取目标变量名:读取用户输入后,从命令行中解析->name部分的变量名,调用变量存储逻辑。
  2. 清理用户输入的换行符:用strcspn移除userInput末尾的\n和\r,避免变量值带多余换行。
  3. 复用变量存储逻辑:将变量创建/赋值的逻辑抽为独立函数,减少重复代码,同时方便在read分支调用。

修改后的完整代码

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

#define MAX_VARIABLES 10

// Structure to store variables
struct Variable {
    char name[50];
    char value[256];
};

// Array to store variables
struct Variable variables[MAX_VARIABLES];
int variableCount = 0;

// Function to find a variable by name
struct Variable *findVariable(const char *name) {
    for (int i = 0; i < variableCount; ++i) {
        if (strcmp(variables[i].name, name) == 0) {
            return &variables[i];
        }
    }
    return NULL; // Variable not found
}

// 独立的变量赋值函数,复用逻辑
int setVariable(const char *name, const char *value) {
    struct Variable *variable = findVariable(name);
    if (variable == NULL) {
        if (variableCount >= MAX_VARIABLES) {
            printf("Maximum number of variables reached\n");
            return 0;
        }
        strncpy(variables[variableCount].name, name, sizeof(variables[variableCount].name)-1);
        variables[variableCount].name[sizeof(variables[variableCount].name)-1] = '\0';
        variable = &variables[variableCount++];
    }
    strncpy(variable->value, value, sizeof(variable->value)-1);
    variable->value[sizeof(variable->value)-1] = '\0';
    return 1;
}

// Function to interpret commands
void interpretCommand(const char *command) {
    if (strncmp(command, "console:write->", 15) == 0) {
        // Extract the message within double quotes
        const char *messageStart = strchr(command, '"');
        const char *messageEnd = strrchr(command, '"');

        if (messageStart != NULL && messageEnd != NULL && messageStart < messageEnd) {
            // Print the message, replacing variables if present
            for (const char *p = messageStart + 1; p < messageEnd; ++p) {
                if (*p == '*') {
                    ++p; // Move past '*'
                    const char *varStart = p;
                    while (*p != '*' && p < messageEnd) {
                        ++p;
                    }

                    char varName[50];
                    strncpy(varName, varStart, p - varStart);
                    varName[p - varStart] = '\0';

                    struct Variable *variable = findVariable(varName);
                    if (variable != NULL) {
                        printf("%s", variable->value);
                    } else {
                        printf("Undefined variable: %s", varName);
                    }
                } else {
                    putchar(*p);
                }
            }
            putchar('\n');
        } else {
            printf("Invalid message format\n");
        }
    } else if (strncmp(command, "console:read->", 14) == 0) {
        // Extract the prompt within double quotes
        const char *promptStart = strchr(command, '"');
        const char *promptEnd = strrchr(command, '"');

        if (promptStart != NULL && promptEnd != NULL && promptStart < promptEnd) {
            // Print the prompt
            printf("%.*s", (int)(promptEnd - promptStart - 1), promptStart + 1);

            // Read user input
            char userInput[256];
            if (fgets(userInput, sizeof(userInput), stdin) == NULL) {
                printf("Failed to read input\n");
                return;
            }

            // 去掉输入末尾的换行符和回车符
            userInput[strcspn(userInput, "\n\r")] = '\0';

            // 提取后面的变量名(->varName部分)
            const char *varArrow = strstr(promptEnd + 1, "->");
            if (varArrow != NULL) {
                const char *varName = varArrow + 2;
                // 调用赋值函数存储变量
                setVariable(varName, userInput);
            } else {
                printf("No variable specified to store input\n");
            }
        } else {
            printf("Invalid prompt format\n");
        }
    } else {
        // Check if the command starts with "variableName->"
        char *arrow = strstr((char*)command, "->");
        if (arrow != NULL) {
            *arrow = '\0'; // Separate variable name and value
            setVariable(command, arrow + 2);
        } else {
            printf("Unknown command\n");
        }
    }
}

int main() {
    // Open the file
    FILE *file = fopen("King.roar", "r");

    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }

    char line[256]; // Assuming a maximum line length of 255 characters

    // Read and interpret each line from the file
    while (fgets(line, sizeof(line), file) != NULL) {
        // Remove newline character if present
        size_t len = strlen(line);
        if (len > 0 && line[len - 1] == '\n') {
            line[len - 1] = '\0';
        }

        // Interpret the command
        interpretCommand(line);
    }

    // Close the file
    fclose(file);

    return 0;
}

关键修改说明

  • 新增setVariable函数,将变量查找、创建、赋值的逻辑抽离,让read分支和普通赋值分支均可复用,减少冗余代码。
  • 在console:read->分支中,读取输入后用strcspn清理换行符,再从命令中提取->后的变量名,调用setVariable存储输入内容。
  • 普通赋值分支直接调用setVariable,简化代码逻辑。

测试验证

运行修改后的代码,执行King.roar脚本,输出示例:

Enter your name: Alice
Enter your age: 30
Hello Alice!
You are 30 years old!

此时变量可正常存储和读取,不会再出现Undefined variable错误。

内容的提问来源于stack exchange,提问作者Hatchy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 05:44:55