C 在Unix中使用文件重定向后,如何重新定义stdin以指向控制台?
我在Unix中工作,我应该首先通过重定向读取文本,然后要求用户输入特定字符,并计算它在字符数组中的次数C 在Unix中使用文件重定向后,如何重新定义stdin以指向控制台?,c,unix,C,Unix,我在Unix中工作,我应该首先通过重定向读取文本,然后要求用户输入特定字符,并计算它在字符数组中的次数 const int MAX = 8000; int input = 1; int i = 0; char text[MAX], letter; while(input != 0) { scanf("%c", &text[i]); if(text[i] == '0') input = 0; i++; } printf("\n%s",text);
const int MAX = 8000;
int input = 1;
int i = 0;
char text[MAX], letter;
while(input != 0)
{
scanf("%c", &text[i]);
if(text[i] == '0')
input = 0;
i++;
}
printf("\n%s",text);
printf("\nEnter a letter to search for in the text: ");
scanf("%c", &letter)
目前,我正在通过重定向打印正确的文件,但是跳过了第二个scanf
。我正在使用命令重定向文件:/a.out
如果我尝试打印字符
字母
,则不会产生任何结果。它必须仍然从文本文件的空行中读取\n
。如何阻止scanf
读取相同的文本文件,并让我在控制台中的键盘上输入字母?作为一项任务,我必须使用命令/a.out
,有几种方法可以做到这一点,可能最简单的方法就是打开/dev/tty
,这是一种特殊的设备,指的是连接到当前进程的终端。我不建议您更换stdin
,因为这样您将无法访问重定向到那里的文件。相反,只需使用不同的文件指针,并使用类似于fscanf
和fgetc
的函数即可。例如:
FILE *tty = fopen("/dev/tty", "r");
// fopen will return NULL if there is no attached terminal
if(NULL == tty)
{
fputs("Failed opening /dev/tty", stderr);
}
else
{
printf("\nEnter a letter to search for in the text: ");
// Read a character from the terminal
char search = fgetc(tty);
// Now you can still read from the file on stdin and search for
// your letter without needing an array (which may not be large
// enough for the whole file)
char ch;
int count = 0;
while(EOF != (ch = getchar())
{
if(ch == search)
++count;
}
printf("%d occurrences of %c\n", count, search);
}
有关/dev/tty
和其他类似特殊文件的更多信息,请参阅:您正需要freopen()
函数。您只需使用它将/dev/tty
重新打开为stdin
/dev/tty
是一个特殊文件,指启动程序的终端
发件人:
freopen()
函数打开名为pathname
指向的字符串的文件,并将stream
指向的流与其关联。原始流(如果存在)已关闭。mode
参数的使用方式与fopen()
函数中的使用方式相同
[……]
函数的主要用途是更改与标准文本流相关联的文件(stderr
、stdin
或stdout
)
下面是一个例子:
// ...
FILE *tty;
tty = freopen("/dev/tty", "r", stdin);
if (tty == NULL) {
perror("Unable to open terminal for reading");
exit(1);
}
printf("Enter a letter to search for in the text: ");
// Now scanf will read from the console where the process started.
scanf("%c", &letter);
顺便说一下,你的程序有一些问题。您可以读取超过
文本
数组结尾的内容,不能正确地用NUL字符终止它,也不能检查错误。更正确的版本是:
const size_t MAX = 8000;
char text[MAX];
size_t i;
int c;
for (i = 0; i < MAX; i++)
{
c = fgetc(stdin);
if (c == EOF)
break;
text[i] = (char)c;
}
text[i] = '\0';
puts(text);
const size\u t MAX=8000;
字符文本[MAX];
尺寸i;
INTC;
对于(i=0;i
可能应该打开它“rw”
并对其进行提示。考虑到这一点,这可能是一个xy问题()。实际上,练习是编写一个grep
类实用程序,预期的解决方案可能是将正在搜索的字符作为命令行参数传递,而不是以交互方式请求它(就像grep
命令一样)。虽然直接访问终端是实现这一点的一种方法,但最好在类Unix系统上使用标准方法(大多数实用程序根本不是交互式的)。