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

我的C语言代码存在什么问题?特定格式输入文件解析求助

常见问题分析与示例代码

Hey Alex, since you only shared the opening lines of your code (the includes), I can’t pinpoint exact bugs, but based on your input parsing requirement, here are the most common pitfalls to check in your code, plus a working example to guide you:

Common Issues to Look For

  • Missing keyword-based parsing logic: If you’re not checking for "REGISTERS", "MEMORY", or "NEXT" tokens, you’ll end up mixing register and memory data. For example, you might accidentally write memory values into the register array, or vice versa.
  • Array out-of-bounds errors: Register numbers (like R1, R7) or memory addresses (like 8,16) could exceed the size of your pre-defined arrays. Without boundary checks, this will cause crashes or silent data corruption.
  • Incorrect register ID extraction: If you try to convert the full "R1" string to an integer directly, you’ll get 0 (since "R" isn’t a digit). You need to extract the numeric part after the "R" to use as the array index.
  • Hardcoded read counts: Since the number of registers and memory entries varies, you can’t write code to read a fixed number of pairs. You need to loop until you hit the next section keyword.
  • No error handling: Not checking if fopen succeeded, or not handling unexpected EOF, will lead to garbage data reads or program crashes.

Working Example Code

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

#define MAX_REGISTERS 32  // Adjust based on your system's register count
#define MAX_MEMORY 256    // Adjust based on your memory address range

int main() {
    FILE *input_file = fopen("your_input_file.txt", "r");
    if (!input_file) {
        perror("Failed to open input file");
        return 1;
    }

    int Registers[MAX_REGISTERS] = {0};  // Initialize all registers to 0
    int MEMORY[MAX_MEMORY] = {0};        // Initialize all memory locations to 0
    char current_token[16];

    // Parse input section by section
    while (fscanf(input_file, "%s", current_token) != EOF) {
        if (strcmp(current_token, "REGISTERS") == 0) {
            char reg_label[16];
            int reg_value;
            // Read register pairs until next section keyword
            while (fscanf(input_file, "%s %d", reg_label, &reg_value) == 2) {
                // Check if we've hit the next section
                if (strcmp(reg_label, "MEMORY") == 0 || strcmp(reg_label, "NEXT") == 0) {
                    // Push the keyword back into the input stream for later parsing
                    for (int i = strlen(reg_label) - 1; i >= 0; i--) {
                        ungetc(reg_label[i], input_file);
                    }
                    break;
                }
                // Validate register label format
                if (reg_label[0] != 'R') {
                    fprintf(stderr, "Invalid register format: %s\n", reg_label);
                    continue;
                }
                // Extract register number from label (e.g., R7 → 7)
                int reg_num = atoi(reg_label + 1);
                // Check for out-of-bounds access
                if (reg_num < 0 || reg_num >= MAX_REGISTERS) {
                    fprintf(stderr, "Register %d is out of bounds (max: %d)\n", reg_num, MAX_REGISTERS - 1);
                    continue;
                }
                Registers[reg_num] = reg_value;
                printf("Updated Registers[%d] = %d\n", reg_num, reg_value);
            }
        } else if (strcmp(current_token, "MEMORY") == 0) {
            int mem_addr, mem_value;
            // Read memory address-value pairs until next section keyword
            while (1) {
                // First try to read an address
                if (fscanf(input_file, "%d", &mem_addr) != 1) break;
                // Then read the corresponding value
                if (fscanf(input_file, "%d", &mem_value) != 1) {
                    // If value read fails, check if we hit a keyword
                    char check_token[16];
                    if (fscanf(input_file, "%s", check_token) == 1) {
                        // Push keyword back and exit loop
                        for (int i = strlen(check_token) - 1; i >= 0; i--) {
                            ungetc(check_token[i], input_file);
                        }
                    }
                    break;
                }
                // Check for out-of-bounds memory access
                if (mem_addr < 0 || mem_addr >= MAX_MEMORY) {
                    fprintf(stderr, "Memory address %d is out of bounds (max: %d)\n", mem_addr, MAX_MEMORY - 1);
                    continue;
                }
                MEMORY[mem_addr] = mem_value;
                printf("Updated MEMORY[%d] = %d\n", mem_addr, mem_value);
                // Peek next token to see if it's a section keyword
                char next_token[16];
                if (fscanf(input_file, "%s", next_token) == 1) {
                    if (strcmp(next_token, "NEXT") == 0 || strcmp(next_token, "REGISTERS") == 0) {
                        // Push keyword back and exit loop
                        for (int i = strlen(next_token) - 1; i >= 0; i--) {
                            ungetc(next_token[i], input_file);
                        }
                        break;
                    } else {
                        // Push non-keyword token back (it's the next memory address)
                        for (int i = strlen(next_token) - 1; i >= 0; i--) {
                            ungetc(next_token[i], input_file);
                        }
                    }
                }
            }
        } else if (strcmp(current_token, "NEXT") == 0) {
            printf("Reached end of current section. Ready for next section.\n");
            // Add logic here if you need to process multiple sections (e.g., reset arrays)
            break;  // Exit after first section in this example
        } else {
            fprintf(stderr, "Unknown token encountered: %s\n", current_token);
        }
    }

    fclose(input_file);
    return 0;
}

Key Notes About the Example

  • Uses section keywords to switch parsing modes, ensuring register and memory data stay separate
  • Extracts register IDs correctly by skipping the "R" prefix
  • Includes boundary checks to prevent array out-of-bounds errors
  • Uses ungetc to push unexpected section keywords back into the input stream, so they’re processed in the correct loop
  • Adds error handling for file opening, invalid formats, and out-of-range accesses

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:43:45