如何为单字符 i/o 定义 getc 和 putc 函数,并提供适当的 i/o 操作缓冲 MIPS

Posted

技术标签:

【中文标题】如何为单字符 i/o 定义 getc 和 putc 函数,并提供适当的 i/o 操作缓冲 MIPS【英文标题】:How to define getc and putc functions for single character i/o, and provide proper buffering of i/o operations MIPS 【发布时间】:2021-07-30 13:30:19 【问题描述】:

(MIPS) 如何为单字符 i/o 定义 getcputc 函数,提供适当的缓冲 strong> 具有 512 字节缓冲区的输入和输入操作。 -火星4.5

【问题讨论】:

您必须分享您正在使用的系统或模拟器。 我在 MARS 4.5 中编写程序集 您是否要像int getc(FILE *stream); 一样提供FILE 类型?是的,这意味着您可能还需要fopen/fclose 才能获得FILE * 缓冲部分相当简单——只是编程的问题,以及缓冲区的一些数据空间。问题是你打算如何完成 C 的 stdio 的实现? 我要写结果。但它需要提供适当的缓冲。不必一次打印出每个字符。 【参考方案1】:

好的,您实际上并不需要getc/putc,只需要一些执行缓冲 I/O 的函数和在某些情况下(例如退出程序)刷新 I/O 的操作。

(目前假设此缓冲不会用于控制台 I/O,即仅文件 I/O — 控制台 I/O 是交互式的,并且在使用 getc 时需要 putc 缓冲区刷新。进一步为简单起见,您只希望能够一次写入一个文件,一次读取一个文件,尽管混合 put/get ok。)

提供两个全局缓冲区,一个用于putc,一个用于getc。与每个缓冲区相关联的还有一个全局变量end,它可以是一个计数或指针,以及一个值max,它可以是编译时间常数或变量,它指示缓冲区大小。此外,putcgetc 中的每一个都是文件描述符变量。 (对于max 的概念,Getc 需要一个真正的变量。)


putc 函数只接受一个参数,即要放置的字符;它应该将字符输入其缓冲区并增加相关联的end — 如果end 达到max,则使用带有参数 putc 文件描述符(全局)、putc 缓冲区(全局) 和 putc max (缓冲区大小)。您选择如何处理错误(使用消息退出程序(可能更简单),或者将错误返回给调用者?)。然后在返回调用者之前将end重置为开头,b/c缓冲区现在是空的。


getc 函数不接受任何参数并返回一个字符或 EOF 指示符,如果缓冲区不为空,则从缓冲区中获取字符以返回,并推进 end 位置。返回之前,如果达到max,则重置到开头。

但是,如果缓冲区为空(即end 位于开头),则使用系统调用#14 使用 getc 文件描述符、getc 缓冲区和 getc 缓冲区大小进行读取。如果该读取调用出错,则再次调用是否将错误打印到控制台并退出程序,或将错误代码返回给用户(前者可能更简单)。如果它返回 0,这意味着 EOF,所以将它(可能是 -1)返回给调用者而不是一个字符。

如果它得到一个非零字符数,则设置max该字符数,并将字符加载到end位置(如果您在这里,则在开头)以返回并增加end 的位置。如果end 的位置是max,则在返回之前将其重置为开头。


初始化:客户端消费者需要将文件描述符放入getcputc 的全局文件描述符中,以便它们与其他全局变量一起使用。

您还需要提供flush 类型的调用,main 或其他调用者应将其用作终止程序之前的最终操作。此刷新操作将使用系统调用 #15 来写入缓冲区中当前有许多字符(如果超过 0,并将指示器重置为空缓冲区)。

客户端还应该关闭 getc/putc 之外的文件,也许还应该清除文件描述符。 (您可以考虑提供执行这些操作的退出调用。)

【讨论】:

以上是关于如何为单字符 i/o 定义 getc 和 putc 函数,并提供适当的 i/o 操作缓冲 MIPS的主要内容,如果未能解决你的问题,请参考以下文章

I/O 函数总结

如何在使用 getc 和 putc 时添加缓冲

c语言输出数字的格式

getc_unlocked,putc_unlocked,getchar_unlocked,putchar_unlocked

C语言中的标准函数都有哪些

C语言中的标准函数都有哪些?