标准输入设备

赤勇玄心行天道 2011-05-11 10:53:17
一般c程序都有3个基本文件描述符:stdin,stdout,stderr。

stdin主要是收集从标准输入设备输入进来的数据,比如键盘。

我现在需要模拟一次输入到stdin,然后用getchar(),scanf()一类的函数读出来,我开始用fwrite("r", 1, 1, stdin); 和 write(STDIN_FILENO, "r", 1); 都没有用,我试过网上说的模拟键盘输入来达到目的,但是只能限于本机,不能用于远程操作,如telnet。

请问各路高手,有办法没?
...全文
123 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
解决了,可以用ungetc()把一个字符退回到输入流中
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 akirya 的回复:]
使用pipe

C/C++ code
#include <windows.h>
#include <tchar.h>
#include <stdio.h>

#define BUFSIZE 4096

HANDLE hChildStdinRd, hChildStdinWr,
hChildStdoutRd, hChildStdoutWr,
hInpu……
[/Quote]

你给的这个程序使用的管道,然后重定向子进程的标准输入、输出流,这样子进程就不能从键盘来输入了。

我是想不修改标准输入设备的情况下,写入数据到标准输入流设备。
  • 打赏
  • 举报
回复
使用pipe

#include <windows.h> 
#include <tchar.h>
#include <stdio.h>

#define BUFSIZE 4096

HANDLE hChildStdinRd, hChildStdinWr,
hChildStdoutRd, hChildStdoutWr,
hInputFile, hStdout;

BOOL CreateChildProcess(VOID);
VOID WriteToPipe(VOID);
VOID ReadFromPipe(VOID);
VOID ErrorExit(LPSTR);

int _tmain(int argc, TCHAR *argv[])
{
SECURITY_ATTRIBUTES saAttr;
BOOL fSuccess;

// Set the bInheritHandle flag so pipe handles are inherited.

saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;

// Get the handle to the current STDOUT.

hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

// Create a pipe for the child process's STDOUT.

if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
ErrorExit("Stdout pipe creation failed\n");

// Ensure the read handle to the pipe for STDOUT is not inherited.

SetHandleInformation( hChildStdoutRd, HANDLE_FLAG_INHERIT, 0);

// Create a pipe for the child process's STDIN.

if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
ErrorExit("Stdin pipe creation failed\n");

// Ensure the write handle to the pipe for STDIN is not inherited.

SetHandleInformation( hChildStdinWr, HANDLE_FLAG_INHERIT, 0);

// Now create the child process.

fSuccess = CreateChildProcess();
if (! fSuccess)
ErrorExit("Create process failed with");

// Get a handle to the parent's input file.

if (argc == 1)
ErrorExit("Please specify an input file");

printf( "\nContents of %s:\n\n", argv[1]);

hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);

if (hInputFile == INVALID_HANDLE_VALUE)
ErrorExit("CreateFile failed");

// Write to pipe that is the standard input for a child process.

WriteToPipe();

// Read from pipe that is the standard output for child process.

ReadFromPipe();

return 0;
}

BOOL CreateChildProcess()
{
TCHAR szCmdline[]=TEXT("child");
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
BOOL bFuncRetn = FALSE;

// Set up members of the PROCESS_INFORMATION structure.

ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );

// Set up members of the STARTUPINFO structure.

ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = hChildStdoutWr;
siStartInfo.hStdOutput = hChildStdoutWr;
siStartInfo.hStdInput = hChildStdinRd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

// Create the child process.

bFuncRetn = CreateProcess(NULL,
szCmdline, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION

if (bFuncRetn == 0)
ErrorExit("CreateProcess failed\n");
else
{
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
return bFuncRetn;
}
}

VOID WriteToPipe(VOID)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];

// Read from a file and write its contents to a pipe.

for (;;)
{
if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||
dwRead == 0) break;
if (! WriteFile(hChildStdinWr, chBuf, dwRead,
&dwWritten, NULL)) break;
}

// Close the pipe handle so the child process stops reading.

if (! CloseHandle(hChildStdinWr))
ErrorExit("Close pipe failed\n");
}

VOID ReadFromPipe(VOID)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];

// Close the write end of the pipe before reading from the
// read end of the pipe.

if (!CloseHandle(hChildStdoutWr))
ErrorExit("Closing handle failed");

// Read output from the child process, and write to parent's STDOUT.

for (;;)
{
if( !ReadFile( hChildStdoutRd, chBuf, BUFSIZE, &dwRead,
NULL) || dwRead == 0) break;
if (! WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL))
break;
}
}

VOID ErrorExit (LPSTR lpszMessage)
{
fprintf(stderr, "%s\n", lpszMessage);
ExitProcess(0);
}

The following is the code for the child process. It uses the inherited handles for STDIN and STDOUT to access the pipe created by the parent. The parent process reads from its input file and writes the information to a pipe. The child receives text through the pipe using STDIN and writes to the pipe using STDOUT. The parent reads from the read end of the pipe and displays the information to its STDOUT.
#include <windows.h> 

#define BUFSIZE 4096

VOID main(VOID)
{
CHAR chBuf[BUFSIZE];
DWORD dwRead, dwWritten;
HANDLE hStdin, hStdout;
BOOL fSuccess;

hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
hStdin = GetStdHandle(STD_INPUT_HANDLE);
if ((hStdout == INVALID_HANDLE_VALUE) ||
(hStdin == INVALID_HANDLE_VALUE))
ExitProcess(1);

for (;;)
{
// Read from standard input.
fSuccess = ReadFile(hStdin, chBuf, BUFSIZE, &dwRead, NULL);
if (! fSuccess || dwRead == 0)
break;

// Write to standard output.
fSuccess = WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL);
if (! fSuccess)
break;
}
}
满衣兄 2011-05-11
  • 打赏
  • 举报
回复
操作远程计算机要用SOCKET

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧