我在 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);
printf("\nEnter a letter to search for in the text: ");
scanf("%c", &letter)
Run Code Online (Sandbox Code Playgroud)
目前,我正在通过重定向打印正确的文件,但是我的第二个文件scanf
被跳过。我使用以下命令重定向文件:./a.out < filename.txt
。
如果我尝试打印该字符,letter
那么它将不会产生任何结果。\n
它必须仍然从文本文件的空行中读取。如何阻止scanf
读取同一文本文件并让我在控制台中从键盘输入字母?作为一项作业,我必须使用该命令./a.out < filename.txt
。
该freopen()
功能正是您所寻找的。您只需使用它来(重新)打开/dev/tty
为stdin
. /dev/tty
是一个特殊文件,指的是启动程序的终端。
从手册页:
该
freopen()
函数打开名称为 by 指向的字符串的文件pathname
,并将指向的流stream
与其关联。原始流(如果存在)被关闭。参数mode
的使用方式与函数中一样fopen()
。[...]
该函数的主要用途是更改与标准文本流( 、、或)
freopen()
关联的文件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);
Run Code Online (Sandbox Code Playgroud)
顺便说一下,你的程序有一些问题。您可以读取超出数组末尾的内容text
,但无法使用 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);
Run Code Online (Sandbox Code Playgroud)
有几种方法可以做到这一点,最简单的可能就是打开/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);
}
Run Code Online (Sandbox Code Playgroud)
有关/dev/tty
其他类似特殊文件的更多信息,请参阅:https://unix.stackexchange.com/questions/60641/linux-difference- Between-dev-console-dev-tty-and-dev-tty0