Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.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 为什么即使输入后面没有换行符,提示也会出现在输入之前? #包括 int main() { 智力年龄; printf(“输入您的年龄:”); 扫描频率(“%lf”、&age); printf(“您的年龄是%d\n”,年龄); 返回0; }_C - Fatal编程技术网

C 为什么即使输入后面没有换行符,提示也会出现在输入之前? #包括 int main() { 智力年龄; printf(“输入您的年龄:”); 扫描频率(“%lf”、&age); printf(“您的年龄是%d\n”,年龄); 返回0; }

C 为什么即使输入后面没有换行符,提示也会出现在输入之前? #包括 int main() { 智力年龄; printf(“输入您的年龄:”); 扫描频率(“%lf”、&age); printf(“您的年龄是%d\n”,年龄); 返回0; },c,C,如果我们运行程序,提示将显示在终端屏幕上,即使提示末尾没有换行符。这是怎么发生的?您可以运行一个实验: #include <stdio.h> int main() { int age; printf("Enter Your age: "); scanf("%lf", &age); printf("Your age is %d\n", age); return 0; } 您将看到10秒后弹出提示。据我所知,它没有文档记录,但在本例中,

如果我们运行程序,提示将显示在终端屏幕上,即使提示末尾没有换行符。这是怎么发生的?

您可以运行一个实验:

#include <stdio.h>
int main()
{
    int age;
    printf("Enter Your age: ");
    scanf("%lf", &age);
    printf("Your age is %d\n", age);
    return 0;

}
您将看到10秒后弹出提示。据我所知,它没有文档记录,但在本例中,
scanf
会导致
stdout
被刷新


但是,您不应该指望这种行为,并且在打印提示字符串时应该
fflush(stdout)

这种情况最有可能发生,因为您的C标准库在其
scanf
的实现中选择刷新输出缓冲区。这是个好主意,因为

  • 这是一个常见的问题,您通常希望提示符与光标和光标位于同一行
  • 这不是性能问题,因为等待用户输入要比刷新缓冲区慢得多

如评论中所述,C标准(ISO/IEC 9899:2011)规定:

§5.1.2.3程序执行 6一致性实施的最低要求是:

  • 对易失性对象的访问严格按照抽象规则进行评估 机器
  • 程序终止时,写入文件的所有数据应与 根据抽象语义执行程序会产生错误
  • 交互设备的输入和输出动态应按照 7.21.3. 这些要求的目的是实现无缓冲或线路缓冲输出 尽快显示,以确保提示消息在 等待输入的程序
这是程序的可观察行为

^7交互设备的构成由实现定义

8抽象语义和实际语义之间更严格的对应关系可由 每个实现

描述
中函数的库部分说:

§7.21.3文件 ^3当流未缓冲时,字符将出现在源或源位置 尽快到达目的地。否则,可能会累积字符并 作为块传输到主机环境或从主机环境传输。当流被完全缓冲时, 在以下情况下,字符将作为块传输到主机环境或从主机环境传输 缓冲区被填满了。当一个流被行缓冲时,字符被指定为 当输入新行字符时,作为块传输到主机环境或从主机环境传输 遇到。此外,字符打算作为块传输到主机 当缓冲区被填满、在未缓冲流上请求输入时,或 当在需要传输数据的线路缓冲流上请求输入时 主机环境中的字符。对这些特性的支持是 已定义实现,并可能通过setbuf和setvbuf函数受到影响

^7在程序启动时,三个文本流是预定义的,不需要显式打开 -标准输入(用于读取常规输入),标准输出(用于写入 常规输出)和标准错误(用于写入诊断输出)。一如当初 打开时,标准错误流未完全缓冲;标准输入与标准 当且仅当可以确定流不引用时,输出流才被完全缓冲 连接到交互式设备

注意§5.1.2.3第6条中的“意图”注释

§7.21.3¨7中的规范意味着标准错误在程序启动时为无缓冲或行缓冲,标准输入和标准输出为无缓冲或行缓冲(通常为行缓冲),除非输出不是交互式设备。在Unix上,磁盘文件、管道、FIFO、套接字(以及其他)都不是交互式的。通常认为
tty
pty
设备是交互式的

因此,如果您在运行程序时将输出发送到管道(例如,到
cat
less
more
),您可能*不会看到提示,但如果您键入数字,您可能会得到提示,然后是第一行输出,并在一行上换行(并且您键入的数字不会出现)。如果从文件重定向输入,则根本看不到输入的值。如果重定向到
cat
,您可能会在一行上看到输入,然后是提示和输出。如果重定向到
更多
,则可能根本看不到您的输入(与响应打印分开)。如果重定向到
less
,可能会得到各种有趣的屏幕效果,但仍然看不到您键入的输入

您还需要修复修改后的代码。
%lf
格式不适合读取整数(它是该代码以前版本的遗留问题)



*由于行为是由实现定义的,因此实际发生的情况取决于您的实现。例如,一个实现可能在任何输入之前执行相当于
fflush(0)
;这将向设备发送提示。但是不需要实现,而且大多数都没有那么彻底(部分原因是这种彻底性会带来运行时成本)。

如果它意识到输出被发送到交互设备,它必须刷新它-通过
更少的
(或
更多的
,或
cat
)然后键入您的号码(稍后才会看到提示)。观察发生了什么。重定向到文件也会起作用。我不认为这算是高级Unix编程
printf("Enter a number: "); /* the prompt */
sleep(10); /* Add this. */
scanf("%lf", &number);