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

C语言Codebreaker游戏数组越界问题及优化方案咨询

Fixing Array Out-of-Bounds Issues in Your C Codebreaker Game

Hey there! Let's tackle those pesky array out-of-bounds bugs and weird variable-overlap behavior in your Codebreaker game. These problems happen because C doesn't enforce array bounds checking—writing past an array's end corrupts adjacent memory, which explains why modifying an int was messing with your arrays. Here's how to fix everything step by step:

First, Identify the Root Causes

  1. Array length mismatch: Your Sectret_CODE2 and guess2 arrays are defined as length 4, but when there are no correct position matches (b=0), t will increment to 4. Writing Sectret_CODE2[t] = '\0'; accesses index 4—way beyond the array's valid 0-3 range. This corrupts nearby memory, causing your unexpected variable behavior.
  2. Unrestricted input: scanf("%s", guess); doesn't limit input length. If a user types more than 4 characters, it'll overflow the guess array and corrupt memory too.
  3. Minor typo: Your global variable is named Sectret_CODE (missing an 'e' in Secret)—not a bug, but it's easy to mix up with Sectret_CODE2 and makes code harder to read.

Step-by-Step Fixes

1. Expand Arrays to Prevent Overflow

Since t can reach a maximum value of 4 (when no positions match), your temporary arrays need enough space for 4 characters plus a null terminator. Change their definitions to:

char Sectret_CODE2[5];  // 5 elements: indexes 0-4 for 4 chars + '\0'
char guess2[5];

This ensures writing the null terminator at index 4 is valid and won't corrupt adjacent memory.

2. Limit Input to Avoid Buffer Overflow

Modify your scanf call to restrict input to 4 characters (since the password is 4 digits):

scanf("%4s", guess);

Add validation to make sure the user entered exactly 4 valid color characters:

// After reading guess
if(strlen(guess) != 4) {
    printf("Error: Guess must be 4 characters long!\n");
    continue;  // Skip to next attempt
}
// Check for valid colors
for(int j=0; j<4; j++) {
    if(!strchr("BGOPRY", guess[j])) {
        printf("Error: Invalid character '%c'! Use B/G/O/P/R/Y.\n", guess[j]);
        continue;
    }
}

This makes the game more robust and prevents invalid input from causing crashes.

3. Fix the 'w' Calculation (Optional but More Accurate)

Your current white peg logic works for most cases, but it can overcount if there are duplicate characters. Let's use marker arrays to track matched characters and avoid double-counting:

// Replace your existing b/w calculation code with this:
int b = 0, w = 0;
int used_secret[4] = {0};  // Track which secret chars are matched
int used_guess[4] = {0};   // Track which guess chars are matched

// First count exact matches (b)
for(int j = 0; j < 4; j++) {
    if(Sectret_CODE[j] == guess[j]) {
        b++;
        used_secret[j] = 1;
        used_guess[j] = 1;
    }
}

// Then count color-only matches (w)
for(int j = 0; j < 4; j++) {
    if(!used_secret[j]) {  // Only check unused secret chars
        for(int k = 0; k < 4; k++) {
            if(!used_guess[k] && Sectret_CODE[j] == guess[k]) {
                w++;
                used_guess[k] = 1;  // Mark guess char as used
                break;
            }
        }
    }
}

This follows standard Codebreaker rules where duplicates are handled correctly (e.g., if the secret is "BBYY" and guess is "BYBY", you get 2b and 2w instead of overcounting).

4. Clean Up the Global Variable (Optional)

Rename Sectret_CODE to Secret_CODE to fix the typo and make code more readable. You can also avoid using a global variable altogether by passing argv[1] directly where needed, but that's a stylistic choice.

Full Fixed Code

Here's the complete code with all the fixes applied:

#include <stdio.h>
#include <string.h>
#define Max_Attempts 12
char *Secret_CODE = NULL;

int main(int argc, char **argv) {
    printf("Available Colors: (B)lue (G)reen (O)range (P)urple (R)ed (Y)ellow\n\n");

    if(argc != 2) {
        fprintf(stderr,"Invalid input: Please provide a 4-character secret code.\n");
        return 1;
    }
    // Validate secret code length
    if(strlen(argv[1]) != 4) {
        fprintf(stderr,"Invalid secret code: Must be 4 characters long.\n");
        return 1;
    }
    Secret_CODE = argv[1];

    int attempts_left = Max_Attempts;
    int won = 0;

    while (attempts_left > 0 && !won) {
        char guess[5];  // 4 chars + null terminator
        printf("No. guesses left: %i\n", attempts_left);
        printf("Enter Your Guess: ");
        scanf("%4s", guess);

        // Validate guess length
        if(strlen(guess) != 4) {
            printf("Error: Guess must be exactly 4 characters!\n\n");
            continue;
        }
        // Validate guess characters
        int valid_guess = 1;
        for(int j=0; j<4; j++) {
            if(!strchr("BGOPRY", guess[j])) {
                printf("Error: Invalid character '%c'! Use only B/G/O/P/R/Y.\n\n", guess[j]);
                valid_guess = 0;
                break;
            }
        }
        if(!valid_guess) continue;

        int b = 0, w = 0;
        int used_secret[4] = {0};
        int used_guess[4] = {0};

        // Count exact matches (b)
        for(int j = 0; j < 4; j++) {
            if(Secret_CODE[j] == guess[j]) {
                b++;
                used_secret[j] = 1;
                used_guess[j] = 1;
            }
        }

        if(b == 4) {
            printf("You Won!\n");
            won = 1;
            return 0;
        }

        // Count color-only matches (w)
        for(int j = 0; j < 4; j++) {
            if(!used_secret[j]) {
                for(int k = 0; k < 4; k++) {
                    if(!used_guess[k] && Secret_CODE[j] == guess[k]) {
                        w++;
                        used_guess[k] = 1;
                        break;
                    }
                }
            }
        }

        printf("Feedback: %i,%i\n\n", b, w);
        attempts_left--;
    }

    if(!won) {
        printf("You Lose! The secret code was: %s\n", Secret_CODE);
    }
    return 0;
}

Key Takeaways

  • Always size arrays to hold their maximum possible content plus a null terminator when dealing with strings.
  • Restrict input lengths with scanf to prevent buffer overflow.
  • Validate all user input to avoid unexpected behavior.
  • Avoid global variables when possible (though it's not a strict requirement here).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 13:37:39