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

使用Python subprocess调用Fortran.exe时遇输入报错求助

解决Python subprocess调用老Fortran程序的输入错误问题

问题分析

你遇到的fmt: end of file错误,是Fortran程序读取标准输入(unit 5)时发现输入提前结束导致的。结合测试情况来看:

  • subprocess.run()能正常支持手动输入,说明程序本身功能正常
  • 添加stdin=subprocess.PIPE后报错,说明输入传递的格式或时机不符合程序预期,常见原因包括:
    • 换行符不匹配(Windows控制台程序期望\r\n而非\n)
    • 输入缓冲未及时刷新,导致程序等待输入时缓冲区为空
    • 老程序可能直接读取控制台硬件输入,而非标准输入流

基础解决方案:调整subprocess参数与输入格式

先尝试修正输入传递方式,确保程序能正确接收输入:

代码示例

import subprocess

program_path = r"D:\PGE\~CIP\code\wain12.exe"
# 构造输入序列:每个输入项后添加Windows标准换行符\r\n,确保程序识别为回车
input_sequence = [
    "输入值1",
    "输入值2",
    "输入值3"
]
input_data = "\r\n".join(input_sequence) + "\r\n"  # 末尾额外加回车,确保程序接收完所有输入

# 启动进程:禁用shell,使用text模式自动处理编码和换行,无缓冲确保输入立即发送
process = subprocess.Popen(
    program_path,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    text=True,
    bufsize=0
)

# 发送输入并等待程序结束
stdout, stderr = process.communicate(input=input_data)

# 打印输出和错误信息用于调试
print("程序输出:")
print(stdout)
if stderr:
    print("错误日志:")
    print(stderr)

关键调整说明

  • text=True:自动处理字符串与字节的转换,同时在Windows环境下自动适配控制台的\r\n换行要求,无需手动编码。
  • bufsize=0:关闭输入缓冲,确保输入内容立即发送给Fortran程序,避免程序因等待输入超时触发EOF错误。
  • 捕获stdout/stderr:防止程序因输出缓冲区满而阻塞,导致输入无法正常传递。
  • 避免shell=True:减少不必要的shell解析层,避免路径或参数的意外解析错误。

备选方案:模拟控制台输入(针对直接读取控制台的老程序)

如果上述方法无效,说明该Fortran程序可能没有读取标准输入,而是直接读取控制台硬件输入。此时需要用Windows API模拟用户手动输入:

步骤1:安装依赖

pip install pywin32

代码示例

import win32api
import win32con
import win32process
import win32gui
import subprocess
import time

program_path = r"D:\PGE\~CIP\code\wain12.exe"

# 启动程序并创建独立控制台窗口
process = subprocess.Popen(
    program_path,
    creationflags=subprocess.CREATE_NEW_CONSOLE
)

# 等待程序启动,确保窗口加载完成
time.sleep(1)

# 根据进程ID获取程序控制台窗口句柄
def get_console_window(pid):
    window_handles = []
    def enum_windows_callback(hwnd, extra):
        _, window_pid = win32process.GetWindowThreadProcessId(hwnd)
        if window_pid == pid and win32gui.GetWindowText(hwnd):
            extra.append(hwnd)
        return True
    win32gui.EnumWindows(enum_windows_callback, window_handles)
    return window_handles[0] if window_handles else None

console_hwnd = get_console_window(process.pid)
if not console_hwnd:
    print("无法找到程序控制台窗口")
    exit()

# 将控制台窗口设为前台,确保输入生效
win32gui.SetForegroundWindow(console_hwnd)

# 模拟键盘输入函数:发送字符串+回车
def send_console_input(text):
    # 逐个字符发送按键事件
    for char in text:
        vk_code = win32api.VkKeyScan(char)
        win32api.keybd_event(vk_code, 0, 0, 0)
        win32api.keybd_event(vk_code, 0, win32con.KEYEVENTF_KEYUP, 0)
    # 模拟回车按键
    win32api.keybd_event(win32con.VK_RETURN, 0, 0, 0)
    win32api.keybd_event(win32con.VK_RETURN, 0, win32con.KEYEVENTF_KEYUP, 0)

# 按顺序发送输入
send_console_input("输入值1")
time.sleep(0.5)  # 等待程序处理输入
send_console_input("输入值2")
time.sleep(0.5)
send_console_input("输入值3")

# 等待程序执行完成
process.wait()

说明

这种方法完全模拟用户手动操作控制台的行为,适用于任何依赖控制台输入的老程序,但需要注意:

  • 程序启动后需要等待足够时间确保窗口加载完成
  • 输入间隔时间可能需要根据程序响应速度调整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 22:37:49