Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在Unix中使用文件重定向后,如何重新定义stdin以指向控制台?_C_Unix - Fatal编程技术网

C 在Unix中使用文件重定向后,如何重新定义stdin以指向控制台?

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);

我在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)
目前,我正在通过重定向打印正确的文件,但是跳过了第二个
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系统上使用标准方法(大多数实用程序根本不是交互式的)。