dasd21a
2020-02-18 17:23
采纳率: 75%
浏览 1.1k

C语言怎么向输入缓冲区写入数据呢?

我想让getchar()获取到程序给出的数据而不是键盘输入的数据。

getchar()函数必须获取到一个字符才会继续运行后面的代码,
但是我想把输入缓冲区写满某个键盘不能直接输入的字符,然后检验getchar()
获取的到字符是不是我程序放到缓冲区的这个字符,
通过这样来检验用户有没有输入。
这样即使用户没有输入程序也会继续运行。

请问该如何实现呢?

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • zqbnqsdsmd 2020-02-18 18:37
    已采纳

    重定向控制台程序的输入输出

    #include <windows.h>  
    #include <tchar.h>
    #include <iostream>
    using namespace std;
    BOOL WriteToPipe();
    // 读出stdout  
    BOOL ReadFromPipe();
    //定义句柄: 构成stdin管道的两端句柄  
    HANDLE  hStdInRead;         //子进程用的stdin的读入端  
    HANDLE  hStdInWrite;        //主程序用的stdin的读入端  
    
    //定义句柄: 构成stdout管道的两端句柄  
    HANDLE  hStdOutRead;     ///主程序用的stdout的读入端  
    HANDLE  hStdOutWrite;    ///子进程用的stdout的写入端  
    
    //定义一个用于产生子进程的STARTUPINFO结构体 (定义见CreateProcess,函数说明)  
    STARTUPINFO siStartInfo;
    //定义一个用于产生子进程的PROCESS_INFORMATION结构体 (定义见CreateProcess,函数说明)  
    PROCESS_INFORMATION piProcInfo;
    
    void main()
    {
        //产生一个用于stdin的管道,得到两个HANDLE:  hStdInRead用于子进程读出数据,hStdInWrite用于主程序写入数据  
        //其中saAttr是一个STARTUPINFO结构体,定义见CreatePipe函数说明  
        SECURITY_ATTRIBUTES saAttr = {0};
        saAttr.nLength = sizeof(saAttr);
        saAttr.bInheritHandle = TRUE;
        if (!CreatePipe(&hStdInRead, &hStdInWrite, &saAttr, 0))
            return;
    
        //产生一个用于stdout的管道,得到两个HANDLE:  hStdInRead用于主程序读出数据,hStdInWrite用于子程序写入数据  
        if (!CreatePipe(&hStdOutRead, &hStdOutWrite, &saAttr, 0))
            return;
    
        //对STARTUPINFO结构体赋值,对stdin,stdout的Handle设置为刚才得到的管道HANDLE  
        ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
        siStartInfo.cb = sizeof(STARTUPINFO);
        siStartInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;  //允许设置showwindow和设置新进程的输入输出句柄参数
        siStartInfo.hStdOutput = hStdOutWrite;     //意思是:子进程的stdout输出到hStdOutWrite  
        siStartInfo.hStdError = hStdOutWrite;        //意思是:子进程的stderr输出到hStdErrWrite  
        siStartInfo.hStdInput = hStdInRead;
    
        //CreateProcess()中使用了CREATE_NEW_CONSOLE后, 可以去掉下面这两句注释
        //siStartInfo.wShowWindow = SW_SHOW;
        //siStartInfo.lpTitle = "新进程标题";
    
        TCHAR CommandLine[] = _T("/c ping 127.0.0.1");  //
        // 产生子进程,具体参数说明见CreateProcess函数  
        BOOL bSuccess = CreateProcess("C:\\Windows\\System32\\cmd.exe",
            CommandLine,    // 子进程的命令行  
            NULL,                   // process security attributes  
            NULL,                   // primary thread security attributes  
            TRUE,                   // handles are inherited  
            CREATE_NO_WINDOW,       // creation flags  如果想新进程显示窗口, 可以设置CREATE_NEW_CONSOLE
            NULL,                  // use parent's environment  
            NULL,                  // use parent's current directory  
            &siStartInfo,      // STARTUPINFO pointer  
            &piProcInfo);     // receives PROCESS_INFORMATION  
    
        //如果失败,退出  
        if (!bSuccess) return;
    
        //然后,就可以读写管道了  
        //写入stdin,具体代码在一个WriteToPipe函数中  
        WriteToPipe();
    
        DWORD process_exit_code = 0;
        //不断子检测进程有否结束  
        while (GetExitCodeProcess(piProcInfo.hProcess, &process_exit_code))
        {
            //读stdout,stderr  
            ReadFromPipe();
            //如果子进程结束,退出循环  
            if (process_exit_code != STILL_ACTIVE) break;
        }
    
        ::CloseHandle(hStdOutWrite);
        ::CloseHandle(hStdInRead);
    
        ::CloseHandle(piProcInfo.hProcess);
        ::CloseHandle(piProcInfo.hThread);
    
    
        system("pause");
    }
    
    
    //写入stdin  
    BOOL WriteToPipe()
    {
        // 本例子中这样写入参数  没有用
        DWORD dwWritten;
        BOOL bSuccess = FALSE;
        CHAR in_buffer[100] = "/c ping 127.0.0.1";
        //用WriteFile,从hStdInWrite写入数据,数据在in_buffer中,长度为dwSize  
        bSuccess = WriteFile(hStdInWrite, in_buffer, 100, &dwWritten, NULL);
        return bSuccess;
    }
    
    // 读出stdout  
    BOOL ReadFromPipe()
    {
        char out_buffer[4096] = { 0 };
        DWORD dwRead;
        BOOL bSuccess = FALSE;
    
        //用WriteFile,从hStdOutRead读出子进程stdout输出的数据,数据结果在out_buffer中,长度为dwRead  
        bSuccess = ReadFile(hStdOutRead, out_buffer, 4096, &dwRead, NULL);
        if ((bSuccess) && (dwRead != 0))  //如果成功了,且长度>0  
        {
            // 此处加入你自己的代码  
            // 比如:将数据写入文件或显示到窗口中  
            cout << endl << "----得到的消息是---" << endl << out_buffer;
        }
        return bSuccess;
    }
    
    

    https://blog.csdn.net/guyue35/article/details/47186797

    解决的话,采纳一下
    解决的话,采纳一下
    解决的话,采纳一下

    已采纳该答案
    6 打赏 评论
  • JonathanYan 2020-02-18 17:33

    系统中输入输出流用的不是一个缓冲区,所以不能用这种方法来判断用户是否输入。
    c和c++大部分的输入检测都是阻塞式的,执行函数直到用户输入才返回。
    可以尝试使用kbhit函数判断是否有输入
    只有键盘输入能向输入缓冲区输入

    打赏 评论

相关推荐 更多相似问题