C:键盘和终端输入

时间:2015-03-29 16:54:09

标签: c input

我只知道如何使用getchar()读取C上的字符,以及  我不想再去K& R教我到目前为止。所以  我想知道是否有任何方法可以使我的程序更通用的程序,让用户输入一个或几个值,并且仍然  能够阅读非常有用的

c = getchar ()) != EOF 

当我做1-20,1-21& 1-22练习我意识到我永远  提供用户无法更改的值,例如:

#define BIG_LINE 16
#define BUFF_SIZE BIG_LINE+2
#define TAB_SIZE 4

  

有没有办法可以使用

$ ./myprogram < file 
     

$ cat file | ./myprogram
     

仍然要求用户输入一个或多个值   两种情况都getchar()

2 个答案:

答案 0 :(得分:0)

没有。您给出的两个示例命令(./myprogram < filecat file | ./myprogram)都指定程序的标准输入管道将用于读取文件,因此getchar()将仅从该文件中检索字符它不能用于从用户那里获得交互式输入。

也许你应该问一个更普遍的问题,比如&#34;是否可以编写一个从文件中读取数据的C程序,还提供一个交互式命令行用户界面,包括提示用户并获得响应?&#34;如果您正在尝试这样做,则可以使用C函数open()fopen()打开输入文件的句柄,同时仍使用标准输入管道和getchar()从用户那里获得交互式输入。

您需要告诉您的程序要打开的文件的路径。路径可以在程序中进行硬编码,也可以来自环境变量,也可以在命令行中作为参数提供(例如,您可以使用./myprogram file运行它。)

答案 1 :(得分:0)

由于您似乎正在使用UNIX-y系统,您通常可以这样做,而不是使用直接getchar()和朋友,而是使用带有文件指针的其他stdio函数(例如fgets()getc()等等,如果你创建了一个指向终端的指针。

例如,以下程序:

#define _POSIX_C_SOURCE 200809L

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define BUFSIZE 1024

/*  Returns a file pointer to the terminal, exits on failure  */

FILE * get_terminal(void)
{
    char * tname = ctermid(NULL);

    int fd = open(tname, O_RDWR);
    if ( fd == -1 ) {
        perror("couldn't open terminal");
        exit(EXIT_FAILURE);
    }

    FILE * fp = fdopen(fd, "r+");
    if ( !fp ) {
        fprintf(stderr, "couldn't make file pointer\n");
        exit(EXIT_FAILURE);
    }

    return fp;
}

/*  Closes a file pointer to the terminal  */

void close_terminal(FILE * fp)
{
    if ( fclose(fp) == EOF ) {
        perror("couldn't close terminal");
        exit(EXIT_FAILURE);
    }
}

/*  Main function  */

int main(void)
{
    FILE * fp = get_terminal();

    char buffer[BUFSIZE];

    /*  Get line from stdin and print to stdout  */

    fgets(buffer, BUFSIZE, stdin);
    fprintf(stdout, "Line 1: %s", buffer, stdout);

    /*  Get string from terminal and print to terminal  */

    fputs("Enter a string: ", fp);
    fflush(fp);
    fgets(buffer, BUFSIZE, fp);
    fprintf(fp, "You entered: %s", buffer);

    /*  Get another line from stdin and print to stdout  */

    fgets(buffer, BUFSIZE, stdin);
    fprintf(stdout, "Line 2: %s", buffer, stdout);

    close_terminal(fp);

    return 0;
}
即使您的shell重定向程序的标准输入和标准输出,

也会提供以下输出:

paul@thoth:~/src/sandbox$ cat input.txt
This is the first line of the file.
This is the second line of the file.

paul@thoth:~/src/sandbox$ ./prog < input.txt > output.txt
Enter a string: This is my string.
You entered: This is my string.
paul@thoth:~/src/sandbox$ cat output.txt
Line 1: This is the first line of the file.
Line 2: This is the second line of the file.
paul@thoth:~/src/sandbox$ 

请注意ctermid()生成的内容不能保证唯一标识终端(实际上,大多数系统都不会 - 通常是/dev/tty)并且您无法保证能够打开它。但它可能适用于现代的UNIX-y个人计算机。

你是否应该这样做完全是另一个问题。在绝大多数情况下,这将是非常不寻常和意外的行为。如果您希望用户能够指定选项卡大小等选项,那么使用命令行参数将比以交互方式获得更好的解决方案,例如:

./prog --tabstop=4 < input.txt > output.txt

K&amp; R涵盖5.10节中的命令行参数,getopt库是一种常用且简单的方法。

对于更持久的选项,使用配置文件甚至读取环境变量是其他可能的解决方案。

显然,以上所有内容远远超过K&amp; R的第1章,但是因为你说“我不想再去K&amp; R教我到目前为止”,然后立即询问如何去到目前为止,K&amp; R已经教会了你,这就是将要发生的事情。在你的情况下,现在最好的选择就是完成剩下的章节,在你完成任务之前,你已经回答了大部分问题。