命令行与C的接口-scanf是如何工作的



重要编辑:从下面的评论中,我知道你们没有注意到我下面的代码有任何问题。在命令行上点击回车键之前,我已经使用了scanf(%c,&[a char variable](输入了多个字符,当我第二次尝试使用它时,scanf没有像正常情况下那样工作。第二次我使用scanf并在命令行上输入内容时,它没有接收我刚刚输入的输入。相反,它存储第一行输入中剩余的内容

好吧,所以我昨天在摆弄我的C代码。我运行了以下代码,看看如果我输入一个单词,而不是像我应该的那样输入一个字母,会发生什么(因为我声明了一个字符,而不是字符数组或字符串。(

如果您输入多个字母,它会记住未能作为输入的剩余字母,然后将其分配给您将在下一个scanf语句中用于分配的变量

附言:我没有故意使用for循环

有人能向我解释为什么会发生这种事吗?scanf是如何工作的如果剩余的输入没有被丢弃,它究竟是如何保存在内存中的

char word;
printf("start %dn", 1);
scanf("%c", &word);
printf("%cnn", word);
printf("start %dn", 2);
scanf("%c", &word);
printf("%cnn", word);
printf("start %dn", 3);
scanf("%c", &word);
printf("%cnn", word);
printf("start %dn", 4);
scanf("%c", &word);

scanf不管理从您的终端或控制台或其他设备读取的任何工作。

在C中,标准输入、标准输出和标准错误是,程序可以手动打开其他流。流是用于管理与文件和设备的连接的结构(软件、数据和算法(。它们由C标准I/O例程的其他部分实现,如fopenfgetc

当您调用scanf时,它一次从流中获取一个字符,并尝试将其与您请求的转换相匹配。当它找到匹配项时,它将数据存储在您传递给它的对象中。当它得到一个不可接受的字符时,它会将其"放回"流中。

流可以是缓冲的,也可以是非缓冲的。如果流被缓冲,流软件会从文件或设备中读取一定数量的数据,并将其保存在内部字符数组中。当scanf或其他例程从流中请求一个或多个字符时,流软件从其数组中提供所请求的数据。流记录它缓冲了多少数据。当缓冲区为空并且请求更多数据时,流软件从文件或设备读取更多数据。缓冲流可以是完全缓冲行缓冲。对于完全缓冲的流,软件尝试在对文件或设备执行另一个I/O操作之前完全填充缓冲区。使用线路缓冲流,软件一次接收或发送一条线路。

即使没有缓冲区的流也保持至少一个字节的缓冲区。这就实现了"放回"功能。当scanf或另一个例程"放回"一个字符时,流软件会记住它,并且当将来请求一个字符,它会首先返回该字符。

不管名称如何,C中的FILE对象都管理一个流。当fopen(代表"文件打开"(被调用时,它会打开一个流。"文件"部分是计算历史遗留下来的;如果我们重新启动它,我们可能会将其称为"sopen",表示"流打开"。stdinstdoutstderr指向程序启动时自动打开的流的FILE对象。fclose关闭流。CCD_ 14和CCD_。这些例程有一些变体,比如从stdin读取的getchar。CCD_ 18和CCD_。这些是直接输入/输出例程。

CCD_ 20是格式化的输入/输出例程之一。它使用getcharfread或等效项来获取字符,然后执行额外的操作来进行匹配和转换。当它完成您请求的转换时,它将停止读取。未读数据仍保留在流中。scanf不会采取任何操作来读取和丢弃该行的其余部分,除非您在格式字符串中使用与该行其余部分匹配的内容明确请求它。

最新更新