如果输入缓冲区不为空,则使用 getchar() 检测 Ctrl+d
Detect Ctrl+d if input buffer is not empty using getchar()
我正在编写一个类似 shell 的解释器,使用 getchar()
进行缓冲输入。
- 如果按下
Enter
,解释器应该处理缓冲区,然后提示换行。
- 如果按下
Ctrl+d
,解释器应该处理缓冲区,然后退出。
下面的代码可以运行,但不完全满足第二个要求。
#include <iostream>
using namespace std;
void shell() {
for (int input;;) {
// prompt at beginning of line
std::cout << ">>> ";
while ((input = getchar()) != '\n') {
// still in current line
if (input == EOF) {
// ctrl+d pressed at beginning of line
return;
}
std::cout << "[" << (char)input << "]";
}
// reached end of line
}
}
int main() {
cout << "before shell" << endl;
shell();
cout << "shell has exited" << endl;
return 0;
}
当缓冲区为空时,我的问题是 getchar()
仅 returns EOF
。按 Ctrl+d
中线会导致 getchar()
到 return 每个缓冲字符 除了 EOF
字符本身。
如何判断Ctrl+d
是否按下中线?
我考虑过使用超时。在此方法中,如果 getchar()
在 return 换行以外的内容后暂停太久,解释器会假定 Ctrl+d
已被按下。这不是我最喜欢的方法,因为它需要线程,引入延迟,并且不清楚适当的等待时间。
普通行的末尾有一个 '\n'
。在 Unix-land shell 中用 Ctrl+D 推送的行不是这样。所以,例如,
#include <stdio.h>
#include <unistd.h> // read
void shell()
{
char line[256];
for( bool finished = false; not finished; )
{
printf( ">>> " );
//fgets( line, sizeof( line ), stdin );
fflush( stdout );
const int n_bytes = read( 0, line, sizeof( line ) - 1 );
line[n_bytes] = '[=10=]';
char const* p = line;
finished = true;
while( char const input = *p++ )
{
if( input == '\n' )
{
finished = false;
break;
}
printf( "[%c]", input );
}
printf( "\n" );
}
}
auto main()
-> int
{
printf( "before shell\n" );
shell();
printf( "shell has exited\n" );
}
请您解决以下问题:
- 处理 EOF(推送空行)。
- 根据 C++ iostream 重写,而不是 C
FILE*
i/o。
- 使用 Ctrl+D 按下的输入行,控制台输出中缺少换行符。
注 1:read
通常也可用于 Windows 编译器。然而,
注意 2:Ctrl+D 用于推送当前行是 Unix 领域的约定。如果您希望您的程序表现出这种行为,无论它是如何 运行 或在什么系统上,您都必须使用一些可移植的低级字符输入库,例如 ncurses。
我正在编写一个类似 shell 的解释器,使用 getchar()
进行缓冲输入。
- 如果按下
Enter
,解释器应该处理缓冲区,然后提示换行。 - 如果按下
Ctrl+d
,解释器应该处理缓冲区,然后退出。
下面的代码可以运行,但不完全满足第二个要求。
#include <iostream>
using namespace std;
void shell() {
for (int input;;) {
// prompt at beginning of line
std::cout << ">>> ";
while ((input = getchar()) != '\n') {
// still in current line
if (input == EOF) {
// ctrl+d pressed at beginning of line
return;
}
std::cout << "[" << (char)input << "]";
}
// reached end of line
}
}
int main() {
cout << "before shell" << endl;
shell();
cout << "shell has exited" << endl;
return 0;
}
当缓冲区为空时,我的问题是 getchar()
仅 returns EOF
。按 Ctrl+d
中线会导致 getchar()
到 return 每个缓冲字符 除了 EOF
字符本身。
如何判断Ctrl+d
是否按下中线?
我考虑过使用超时。在此方法中,如果 getchar()
在 return 换行以外的内容后暂停太久,解释器会假定 Ctrl+d
已被按下。这不是我最喜欢的方法,因为它需要线程,引入延迟,并且不清楚适当的等待时间。
普通行的末尾有一个 '\n'
。在 Unix-land shell 中用 Ctrl+D 推送的行不是这样。所以,例如,
#include <stdio.h>
#include <unistd.h> // read
void shell()
{
char line[256];
for( bool finished = false; not finished; )
{
printf( ">>> " );
//fgets( line, sizeof( line ), stdin );
fflush( stdout );
const int n_bytes = read( 0, line, sizeof( line ) - 1 );
line[n_bytes] = '[=10=]';
char const* p = line;
finished = true;
while( char const input = *p++ )
{
if( input == '\n' )
{
finished = false;
break;
}
printf( "[%c]", input );
}
printf( "\n" );
}
}
auto main()
-> int
{
printf( "before shell\n" );
shell();
printf( "shell has exited\n" );
}
请您解决以下问题:
- 处理 EOF(推送空行)。
- 根据 C++ iostream 重写,而不是 C
FILE*
i/o。 - 使用 Ctrl+D 按下的输入行,控制台输出中缺少换行符。
注 1:read
通常也可用于 Windows 编译器。然而,
注意 2:Ctrl+D 用于推送当前行是 Unix 领域的约定。如果您希望您的程序表现出这种行为,无论它是如何 运行 或在什么系统上,您都必须使用一些可移植的低级字符输入库,例如 ncurses。