getchar() 在哪里存储用户输入?

发布于 2024-07-24 22:59:56 字数 892 浏览 4 评论 0原文

我开始阅读“C 编程语言”(K&R)我对 getchar() 函数有疑问。

例如以下代码:

#include <stdio.h>

main()
{
  int c;

  c = getchar();
  putchar(c);
  printf("\n");   
}

输入 tooomychars + CTRL+D (EOF) 仅打印 t。 我认为这是预料之中的,因为这是第一个引入的角色。

但是另一段代码:

#include <stdio.h>

main()
{
  int c;

  while((c = getchar()) != EOF) 
    putchar(c);
}

输入 tooomychars + CTRL+D (EOF) 会打印 tooomychars

我的问题是,如果我只有一个 char 变量,为什么会发生这种情况? 其余字符存储在哪里?

编辑:

感谢大家的回答,我现在开始明白了......只有一个问题:

第一个程序在给定 CTRL+D 而第二个则打印整个字符串,然后等待更多的用户输入。 为什么它等待另一个字符串并且不像第一个字符串那样退出?

I've started reading "The C Programming Language" (K&R) and I have a doubt about the getchar() function.

For example this code:

#include <stdio.h>

main()
{
  int c;

  c = getchar();
  putchar(c);
  printf("\n");   
}

Typing toomanychars + CTRL+D (EOF) prints just t. I think that's expected since it's the first character introduced.

But then this other piece of code:

#include <stdio.h>

main()
{
  int c;

  while((c = getchar()) != EOF) 
    putchar(c);
}

Typing toomanychars + CTRL+D (EOF) prints toomanychars.

My question is, why does this happens if I only have a single char variable? where are the rest of the characters stored?

EDIT:

Thanks to everyone for the answers, I start to get it now... only one catch:

The first program exits when given CTRL+D while the second prints the whole string and then waits for more user input. Why does it waits for another string and does not exit like the first?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

财迷小姐 2024-07-31 22:59:56

getchar 从标准输入获取单个字符,在本例中为键盘缓冲区。

在第二个示例中,getchar 函数位于 while 循环中,该循环一直持续到遇到 EOF,因此它将继续循环并检索字符(并将该字符打印到屏幕上),直到输入变空。

连续调用 getchar 将获取来自输入的连续字符。

哦,不要因为问这个问题而感到难过——当我第一次遇到这个问题时我也很困惑。

getchar gets a single character from the standard input, which in this case is the keyboard buffer.

In the second example, the getchar function is in a while loop which continues until it encounters a EOF, so it will keep looping and retrieve a character (and print the character to screen) until the input becomes empty.

Successive calls to getchar will get successive characters which are coming from the input.

Oh, and don't feel bad for asking this question -- I was puzzled when I first encountered this issue as well.

看海 2024-07-31 22:59:56

它将输入流视为文件。 就好像您打开了一个包含文本“tooomychars”的文件,并一次读取或输出一个字符。

在第一个示例中,在没有 while 循环的情况下,就像打开一个文件并读取第一个字符,然后输出它。 但是,第二个示例将继续读取字符,直到收到文件结束信号(在您的情况下为 ctrl+D),就像从磁盘上的文件读取一样。


在回答您更新的问题时,您使用的是什么操作系统? 我在我的 Windows XP 笔记本电脑上运行它并且运行良好。 如果我按回车键,它会打印出到目前为止的内容,换行,然后继续。 (getchar() 函数在您按 Enter 之前不会返回,即调用该函数时输入缓冲区中没有任何内容)。 当我按 CTRL+Z(Windows 中的 EOF)时,程序终止。 请注意,在 Windows 中,EOF 必须单独占一行才能在命令提示符中算作 EOF。 我不知道 Linux 或您可能运行的任何系统是否模仿这种行为。

It's treating the input stream like a file. It is as if you opened a file containing the text "toomanychars" and read or outputted it one character at a time.

In the first example, in the absence of a while loop, it's like you opened a file and read the first character, and then outputted it. However the second example will continue to read characters until it gets an end of file signal (ctrl+D in your case) just like if it were reading from a file on disk.


In reply to your updated question, what operating system are you using? I ran it on my Windows XP laptop and it worked fine. If I hit enter, it would print out what I had so far, make a new line, and then continue. (The getchar() function doesn't return until you press enter, which is when there is nothing in the input buffer when it's called). When I press CTRL+Z (EOF in Windows), the program terminates. Note that in Windows, the EOF must be on a line of its own to count as an EOF in the command prompt. I don't know if this behavior is mimicked in Linux, or whatever system you may be running.

川水往事 2024-07-31 22:59:56

这里有些东西被缓冲了。 例如 putchar 写入的 stdout FILE* 可能是 line.buffered。 当程序结束(或遇到换行符)时,这样的 FILE* 将被 fflush() 编辑,您将看到输出。

在某些情况下,您正在查看的实际终端可能会缓冲输出,直到出现换行符,或者直到终端本身被指示刷新其缓冲区,这可能是当前前台程序退出时的情况,因为它想要呈现新的提示。

现在,这里的实际情况可能是,它是缓冲的输入(除了输出:-))当您按下按键时,它会出现在终端窗口上。 然而,终端不会将这些字符发送到您的应用程序,它会缓冲它,直到您使用 Ctrl+D 指示它作为输入结束,也可能是换行符。
这是另一个可供尝试和思考的版本:

int main() {
  int c;
   while((c = getchar()) != EOF) {
     if(c != '\n')
        putchar(c);
   }
    return 0;
}

尝试向您的程序输入一个句子,然后按 Enter 键。 如果您注释掉,请执行相同的操作
if(c != '\n') 也许您可以确定您的输入、输出或两者是否以某种方式缓冲。
如果你运行上面的代码,这会变得更有趣:
./mytest | ./mytest

(作为旁注,请注意 CTRD+D 不是字符,也不是 EOF。但在某些系统上,它会导致关闭输入流,这将再次向任何尝试从流中读取数据的人提出 EOF。)

Something here is buffered. e.g. the stdout FILE* which putchar writes to might be line.buffered. When the program ends(or encounters a newline) such a FILE* will be fflush()'ed and you'll see the output.

In some cases the actual terminal you're viewing might buffer the output until a newline, or until the terminal itself is instructed to flush it's buffer, which might be the case when the current foreground program exits sincei it wants to present a new prompt.

Now, what's likely to be the actual case here, is that's it's the input that is buffered(in addition to the output :-) ) When you press the keys it'll appear on your terminal window. However the terminal won't send those characters to your application, it will buffer it until you instruct it to be the end-of-input with Ctrl+D, and possibly a newline as well.
Here's another version to play around and ponder about:

int main() {
  int c;
   while((c = getchar()) != EOF) {
     if(c != '\n')
        putchar(c);
   }
    return 0;
}

Try feeding your program a sentence, and hit Enter. And do the same if you comment out
if(c != '\n') Maybe you can determine if your input, output or both are buffered in some way.
THis becomes more interesting if you run the above like:
./mytest | ./mytest

(As sidecomment, note that CTRD+D isn't a character, nor is it EOF. But on some systems it'll result closing the input stream which again will raise EOF to anyone attempting to read from the stream.)

冷月断魂刀 2024-07-31 22:59:56

您的第一个程序仅读取一个字符,将其打印出来,然后退出。 你的第二个程序有一个循环。 它会一次读取一个字符并将其打印出来,直到读取到 EOF 字符为止。 在任何给定时间仅存储一个字符。

Your first program only reads one character, prints it out, and exits. Your second program has a loop. It keeps reading characters one at a time and printing them out until it reads an EOF character. Only one character is stored at any given time.

您仅使用变量 c 一次包含每个字符。

使用 putchar(c) 显示第一个字符 (t) 后,您会通过分配下一个字符而忘记 c 的值(o) 到变量 c,替换之前的值 (t)。

You're only using the variable c to contain each character one at a time.

Once you've displayed the first char (t) using putchar(c), you forget about the value of c by assigning the next character (o) to the variable c, replacing the previous value (t).

忘你却要生生世世 2024-07-31 22:59:56

该代码在功能上等效,

main(){
  int c;
  c = getchar();
  while(c != EOF) {
    putchar(c);
    c = getchar();
  }
}

您可能会发现此版本更容易理解。 将赋值放入条件中的唯一原因是避免键入“c=getchar()”两次。

the code is functionally equivalent to

main(){
  int c;
  c = getchar();
  while(c != EOF) {
    putchar(c);
    c = getchar();
  }
}

you might find this version easier to understand. the only reason to put the assignment in the conditional is to avoid having to type 'c=getchar()' twice.

彡翼 2024-07-31 22:59:56

对于您更新的问题,在第一个示例中,仅读取一个字符。 它永远不会到达 EOF。 程序终止,因为它在完成 printf 指令后无事可做。 它只读取一个字符。 打印它。 放入换行符。 然后终止,因为它没有更多事情可做。 它不会读取超过一个字符。

而在第二个代码中,getchar 和 putchar 出现在 while 循环内。 在此,程序继续一一读取字符(因为循环是这样做的),直到达到 EOF 字符 (^D)。 此时,它匹配 c!=EOF,并且由于条件不满足,因此它退出循环。 现在没有更多的语句要执行。 所以程序到这里就终止了。

希望这可以帮助。

For your updated question, in the first example, only one character is read. It never reaches the EOF. The program terminates because there is nothing for it to do after completing the printf instruction. It just reads one character. Prints it. Puts in a newline. And then terminates as it has nothing more to do. It doesn't read more than one character.

Whereas, in the second code, the getchar and putchar are present inside a while loop. In this, the program keeps on reading characters one by one (as it is made to do so by the loop) until reaches reaches the EOF character (^D). At that point, it matches c!=EOF and since the conditions is not satisfied, it comes out of the loop. Now there are no more statements to execute. So the program terminates at this point.

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文