磊之茶 发表于 3 天前

请问为何改掉乱码就不能运行?

本帖最后由 磊之茶 于 2026-8-19 15:21 编辑

我用AI写代码,复制时不知道怎么地成乱码了但是可以运行
/*
* ============================================================================
* TypingSimulator - 鏂囨湰鏂囦欢妯℃嫙閿洏杈撳叆宸ュ叿
* ============================================================================
* 閫傜敤锛歐indows 11 + 鍗庣绗旇鏈紙瀹為檯鏀寔鎵

磊之茶 发表于 3 天前

发帖子时出错了,以下是乱码版

磊之茶 发表于 3 天前

本帖最后由 磊之茶 于 2026-8-19 15:20 编辑

/*
* ============================================================================
* TypingSimulator - 鏂囨湰鏂囦欢妯℃嫙閿洏杈撳叆宸ュ叿
* ============================================================================
* 鍔熻兘锛氳鍙?TXT 鏂囦欢鍐呭锛岄

磊之茶 发表于 3 天前

本帖最后由 磊之茶 于 2026-8-19 15:25 编辑

乱码版发不出来,只能像上面那样只有一小段,其余发布后异常消失
以下是修改版
/*
* ============================================================================
* TypingSimulator - 文本文件模拟键盘输入工具
* ============================================================================
* 功能:读取 TXT 文件内容,通过 SendInput API 逐字模拟键盘输入
*       可绕过网页的"禁止粘贴"限制(因为本质是模拟硬件键盘事件)
*
* 适用:Windows 11 + 华为笔记本(实际支持所有 Windows 系统)
* 编译:gcc typing_simulator.c -o typing_simulator.exe -luser32 -mwindows
*       或 cl typing_simulator.c user32.lib
*
* 使用流程:
*   1. 运行程序,输入 TXT 文件路径
*   2. 程序倒计时 5 秒(给你时间切换到目标网页输入框)
*   3. 自动开始逐字"打字"输入文件内容
*
* 注意:
*   - TXT 文件请保存为 UTF-8 编码(含 BOM 也可)
*   - 输入前请确保目标输入框已获得焦点(光标在闪烁)
*   - 输入过程中不要动键盘鼠标,以免干扰
* ============================================================================
*/

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

/*
* 发送单个 Unicode 字符(核心函数)
* 原理:使用 SendInput + KEYEVENTF_UNICODE
* 这种方式直接向系统输入队列注入 Unicode 字符,
* 完全绕过了输入法和粘贴检测机制
*/
void SendUnicodeChar(wchar_t ch)
{
    INPUT input = {0};

    /* 按下事件 */
    input.type = INPUT_KEYBOARD;
    input.ki.wVk = 0;                /* 使用 Unicode 时 wVk 必须为 0 */
    input.ki.wScan = ch;             /* 直接填充 Unicode 字符 */
    input.ki.dwFlags = KEYEVENTF_UNICODE;
    input.ki.time = 0;
    input.ki.dwExtraInfo = 0;

    /* 释放事件 */
    input.type = INPUT_KEYBOARD;
    input.ki.wVk = 0;
    input.ki.wScan = ch;
    input.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
    input.ki.time = 0;
    input.ki.dwExtraInfo = 0;

    SendInput(2, input, sizeof(INPUT));
}

/*
* 发送一个虚拟键(用于发送回车、Tab 等特殊键)
*/
void SendVirtualKey(WORD vk)
{
    INPUT input = {0};

    input.type = INPUT_KEYBOARD;
    input.ki.wVk = vk;
    input.ki.dwFlags = 0;

    input.type = INPUT_KEYBOARD;
    input.ki.wVk = vk;
    input.ki.dwFlags = KEYEVENTF_KEYUP;

    SendInput(2, input, sizeof(INPUT));
}

/*
* 模拟"打字"一个字符串
* text   : 要输入的宽字符字符串
* charDelay: 每个字符之间的延迟(毫秒),推荐 30~100
*/
void SimulateTyping(const wchar_t* text, int charDelay)
{
    for (int i = 0; text != L'\0'; i++)
    {
      wchar_t ch = text;

      if (ch == L'\n')
      {
            /* 换行 -> 发送回车键 */
            SendVirtualKey(VK_RETURN);
      }
      else if (ch == L'\t')
      {
            /* Tab -> 发送 Tab 键 */
            SendVirtualKey(VK_TAB);
      }
      else if (ch == L'\r')
      {
            /* 忽略 \r(Windows 换行符的一部分) */
            continue;
      }
      else
      {
            /* 普通字符(含中文)-> Unicode 方式发送 */
            SendUnicodeChar(ch);
      }

      /* 字符间延迟,模拟真人打字节奏 */
      if (charDelay > 0)
            Sleep(charDelay);
    }
}

/*
* 读取 UTF-8 编码的文本文件,返回宽字符字符串
* 自动处理 BOM(字节顺序标记)
*/
wchar_t* ReadTxtFileToWString(const char* filePath)
{
    FILE* fp = fopen(filePath, "rb");/* 二进制模式打开 */
    if (fp == NULL)
    {
      printf("[错误] 无法打开文件: %s\n", filePath);
      return NULL;
    }

    /* 获取文件大小 */
    fseek(fp, 0, SEEK_END);
    long fileSize = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    if (fileSize <= 0)
    {
      printf("[错误] 文件为空或读取失败\n");
      fclose(fp);
      return NULL;
    }

    /* 读取全部字节 */
    char* utf8Bytes = (char*)malloc(fileSize + 1);
    if (utf8Bytes == NULL)
    {
      printf("[错误] 内存分配失败\n");
      fclose(fp);
      return NULL;
    }
    fread(utf8Bytes, 1, fileSize, fp);
    utf8Bytes = '\0';
    fclose(fp);

    /* 跳过 UTF-8 BOM(EF BB BF) */
    char* ptr = utf8Bytes;
    if (fileSize >= 3 &&
      (unsigned char)utf8Bytes == 0xEF &&
      (unsigned char)utf8Bytes == 0xBB &&
      (unsigned char)utf8Bytes == 0xBF)
    {
      ptr += 3;
    }

    /* 计算转换后的宽字符长度 */
    int wideLen = MultiByteToWideChar(CP_UTF8, 0, ptr, -1, NULL, 0);
    if (wideLen == 0)
    {
      printf("[错误] UTF-8 转宽字符失败(错误码: %lu)\n", GetLastError());
      free(utf8Bytes);
      return NULL;
    }

    /* 分配并转换 */
    wchar_t* wideStr = (wchar_t*)malloc(wideLen * sizeof(wchar_t));
    if (wideStr == NULL)
    {
      printf("[错误] 宽字符内存分配失败\n");
      free(utf8Bytes);
      return NULL;
    }
    MultiByteToWideChar(CP_UTF8, 0, ptr, -1, wideStr, wideLen);

    free(utf8Bytes);
    return wideStr;
}

/*
* 倒计时提示
*/
void Countdown(int seconds)
{
    for (int i = seconds; i > 0; i--)
    {
      printf("\r倒计时 %2d 秒 —— 请切换到目标网页输入框...", i);
      fflush(stdout);
      Sleep(1000);
    }
    printf("\r倒计时结束!开始输入!                        \n");
}

/*
* 清屏后打印程序标题
*/
void PrintBanner(void)
{
    printf("\n");
    printf("========================================\n");
    printf("=      TypingSimulator - 模拟键盘输入工具 v1.0          =\n");
    printf("=                                                       =\n");
    printf("= 原理: SendInput + KEYEVENTF_UNICODE                   =\n");
    printf("= 效果: 模拟真实键盘逐字输入,绕过网页禁止粘贴限制       =\n");
    printf("= 适用: Windows 11 (华为/联想/戴尔等所有品牌)         =\n");
    printf("========================================================\n\n");
}

int main(int argc, char* argv[])
{
    PrintBanner();

    /* ---------- 1. 获取文件路径 ---------- */
    char filePath;

    if (argc > 1)
    {
      strcpy(filePath, argv);
    }
    else
    {
      printf("请输入 TXT 文件路径(支持拖拽文件到窗口)\n> ");
      fgets(filePath, MAX_PATH, stdin);
      /* 去掉换行符 */
      filePath = '\0';
    }

    if (strlen(filePath) == 0)
    {
      printf("[错误] 文件路径为空\n");
      system("pause");
      return 1;
    }

    /* ---------- 2. 读取文件内容 ---------- */
    printf("\n[信息] 正在读取文件: %s\n", filePath);

    wchar_t* text = ReadTxtFileToWString(filePath);
    if (text == NULL)
    {
      system("pause");
      return 1;
    }

    /* 统计字符数 */
    int charCount = wcslen(text);
    printf("[信息] 文件读取成功,共 %d 个字符\n", charCount);

    /* 预览前 100 个字符 */
    wprintf(L"[预览] %.*s%s\n",
            (charCount > 50 ? 50 : charCount), text,
            (charCount > 50 ? L"..." : L""));

    /* ---------- 3. 获取输入速度 ---------- */
    int delayMs = 50;/* 默认 50ms */
    printf("\n请输入每个字符之间的延迟(毫秒),默认 50,回车确认\n> ");
    char delayInput;
    fgets(delayInput, 32, stdin);
    delayInput = '\0';
    if (strlen(delayInput) > 0)
    {
      int parsed = atoi(delayInput);
      if (parsed >= 0 && parsed <= 5000)
            delayMs = parsed;
    }
    printf("[信息] 延迟设置为 %d ms/字符\n", delayMs);

    /* ---------- 4. 倒计时 ---------- */
    printf("\n[提示] 你有 5 秒钟时间切换到目标网页,并点击输入框让光标闪烁\n");
    Countdown(5);

    /* ---------- 5. 开始模拟输入 ---------- */
    printf("[运行] 正在模拟键盘输入...\n");

    /*
   * 先检查一下当前前台窗口,提醒用户
   */
    HWND fg = GetForegroundWindow();
    if (fg == NULL)
      printf("[警告] 未检测到前台窗口,请确认已切换到目标网页\n");

    /*
   * 核心调用:逐字模拟输入
   * 使用 Unicode 方式,中文/英文/标点全部兼容
   */
    SimulateTyping(text, delayMs);

    printf("[完成] 输入完毕!共输入 %d 个字符\n", charCount);

    /* 清理 */
    free(text);

    printf("\n按任意键退出...");
    system("pause >nul");
    return 0;
}
修改版不能运行但是乱码版正常运行,修改版仅仅修改了注释和中文部分

磊之茶 发表于 3 天前

本帖最后由 磊之茶 于 2026-8-19 15:21 编辑

我的求助是改一下,使其能够正常运行,还有为什么乱码可以运行

磊之茶 发表于 3 天前

对了,其实我自己知道乱码版看起来就一堆问题,疑似有严重bug比如%s 不能用于 wchar_t*

磊之茶 发表于 3 天前

本帖最后由 磊之茶 于 2026-8-19 18:31 编辑

报错是:254        13        C:\Users\67428\Desktop\超级无敌大输入啊啊.c        converting to execution character set: Illegal byte sequence
还有55        5        C:\Users\67428\Desktop\驶入输入.c        incompatible type for argument 2 of 'SendInput'

小甲鱼的二师兄 发表于 前天 01:29

乱码是因为 Windows 的编码问题吧?是使用 VSCode 吗?

磊之茶 发表于 前天 20:34

本帖最后由 磊之茶 于 2026-8-21 06:42 编辑

小甲鱼的二师兄 发表于 2026-8-20 01:29
乱码是因为 Windows 的编码问题吧?是使用 VSCode 吗?

应该是编码问题,我用DevC++编译器,而且经过排查,wprintf(L"[棰勮] %.*s%s\n",
            (charCount > 50 ? 50 : charCount), text,
            (charCount > 50 ? L"..." : L""));是唯一一句不能改掉乱码的,而且这句不能运行,我怀疑是DEVC++的环境问题导致我看似只动了一个字,实则破坏了中文的编码,但是我就算不动也不能实现这个预览要复制的文本的前50个文字的功能,请问我推测得对吗?以及能否修复预览要复制的文本的前50个文字的功能还是说这个功能同样因为编码问题导致不能运行
页: [1]
查看完整版本: 请问为何改掉乱码就不能运行?