我只知道如何使用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()
?
答案 0 :(得分:0)
没有。您给出的两个示例命令(./myprogram < file
和cat 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已经教会了你,这就是将要发生的事情。在你的情况下,现在最好的选择就是完成剩下的章节,在你完成任务之前,你已经回答了大部分问题。