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

C语言读取stdin创建结构体时遇0/2中断的问题求助

C语言输入读取崩溃问题的分析与解决

问题描述

尝试从标准输入读取以下格式的内容,用来创建结构体并填充状态,但程序读取到0或2时停止运行:

3
0 -1 1 -1 2
2 0 -1 -1 -1
2 -1 -1 0 -1
4
1 0
1 2
2 2
0 1

程序可正常编译,但运行时出现类似如下错误(注:该错误实际是PowerShell的解析错误,并非C程序本身的错误):

2 0 -1 -1 -1
ParserError:
Line |
1 | 2 0 -1 -1 -1
| ~
| Unexpected token '0' in expression or statement.

代码问题排查与修复

1. scanf参数未传地址,导致未定义行为

scanf读取变量时必须传入变量的地址(指针),原代码中读取结构体成员时直接传递了成员变量的值,会导致程序内存访问错误,这是崩溃的核心原因。

  • 原错误代码:
    scanf("%d %d %d %d %d", rooms[i].state, rooms[i].northState, rooms[i].southState, rooms[i].eastState, rooms[i].westState);
    
  • 修正后:
    scanf("%d %d %d %d %d", &rooms[i].state, &rooms[i].northState, &rooms[i].southState, &rooms[i].eastState, &rooms[i].westState);
    
  • 读取Creature结构体时同理,需给成员变量加&:
    scanf("%d %d", &creatures[i].type, &creatures[i].location);
    

2. getCurrentRoom函数参数与调用不匹配

  • 调用getCurrentRoom时,creatures是数组名,本身就是指向数组首元素的指针,不需要加&,原代码&creatures会传递数组的地址(双重指针),与函数参数类型不匹配。
  • 函数循环条件错误:遍历生物列表应该用生物的数量,而非房间数量,参数名需修正避免混淆。
  • 函数缺少默认返回值:如果找不到type为0的生物,函数无返回值会导致未定义行为,需添加默认返回。

修正后的getCurrentRoom函数及调用:

// 函数定义修正参数名
int getCurrentRoom(int nrOfCreatures, struct Creature *creature) {
    for(int i = 0; i < nrOfCreatures; i++) {
        if (creature[i].type == 0){
            return creature[i].location;
        }
    }
    return -1; // 默认返回,避免未定义行为
}

// 调用修正
int playerLocation = getCurrentRoom(nrOfCreatures, creatures);

3. strupr函数的可移植性问题

strupr不是C标准库函数,部分编译器(如GCC)不支持,建议手动实现字符串转大写的逻辑:

void toUpper(char *str) {
    while (*str) {
        *str = toupper((unsigned char)*str);
        str++;
    }
}

// 替换原strupr调用
toUpper(input);
if(strcmp(input, "LOOK") == 0) {
    // ...
}

注意需要包含ctype.h头文件。

4. 错误提示的正确理解

你看到的ParserError是PowerShell的错误,原因是直接在PowerShell命令行输入了程序的输入内容,而非将输入传递给编译后的可执行程序。正确的运行方式:

  • 编译程序生成可执行文件(如game.exe)
  • 方式一:运行程序后手动输入所有内容
  • 方式二:将输入内容保存到input.txt,执行./game.exe < input.txt

修正后的完整代码

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

void toUpper(char *str);
int getNrOfX();
int getCurrentRoom(int nrOfCreatures, struct Creature *creature);

struct Room {
    int state;
    int northState;
    int southState;
    int eastState;
    int westState;
};

struct Creature {
    int type;
    int location;
};

int main() {
    // 创建初始房间和生物
    int nrOfRooms = getNrOfX();
    struct Room rooms[nrOfRooms];
    
    for(int i = 0; i < nrOfRooms; i++){
        scanf("%d %d %d %d %d", &rooms[i].state, &rooms[i].northState, &rooms[i].southState, &rooms[i].eastState, &rooms[i].westState);
    }
    
    int nrOfCreatures = getNrOfX();
    struct Creature creatures[nrOfCreatures];
    
    for(int i = 0; i < nrOfCreatures; i++){
        scanf("%d %d", &creatures[i].type, &creatures[i].location);
    }
    
    // 游戏循环
    while (1) {
        char input[30];
        scanf("%s", input);
        
        toUpper(input);
        if(strcmp(input, "LOOK") == 0) {
            int playerLocation = getCurrentRoom(nrOfCreatures, creatures);
            if (playerLocation != -1) {
                printf("Room State %d\n", rooms[playerLocation].state);
                printf("%d\n", rooms[playerLocation].northState);
            } else {
                printf("Player not found\n");
            }
            break;
        }
    }

    return 0;
}

int getNrOfX() {
    int nrOfX;
    scanf("%d", &nrOfX);
    return nrOfX;
}

int getCurrentRoom(int nrOfCreatures, struct Creature *creature) {
    for(int i = 0; i < nrOfCreatures; i++) {
        if (creature[i].type == 0){
            return creature[i].location;
        }
    }
    return -1;
}

void toUpper(char *str) {
    while (*str) {
        *str = toupper((unsigned char)*str);
        str++;
    }
}

内容的提问来源于stack exchange,提问作者Xander O'Hara

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 02:35:26