This article aims to clarify all input and output issues in the C language. It provides a complete explanation from multiple aspects. It is recommended to bookmark this article.
1. Overview
1. Classification by IO Location

According to the location of IO, it can be divided into <span>standard IO</span> (i.e., keyboard, screen), <span>files</span>, and <span>memory</span>.
2. Classification by IO Data Type

Classified by data type, it includes <span>character IO</span>, <span>string IO</span>, <span>formatted string IO</span>, and <span>binary IO</span>.
In summary, there are two dimensions: <span>IO location</span> and <span>IO data type</span>, so the C source library must provide corresponding IO functions. As follows:

Detailed as follows:
1. Character IO

2. String IO

3. Formatted String IO

4. Binary IO

2. Detailed Explanation
1. Character IO

1.1 Standard IO
getchar
Prototype: <span>int getchar (void){return getc (stdin);}</span>
It can be seen that it is equivalent to <span>getc(stdin)</span>, which is actually a more general version, indicating that the data source is the screen.
putchar
Prototype: <span>putchar (int __c){return putc (__c, stdout);}</span>
Similarly, this is equivalent to <span>putc(stdin)</span>
1.2 File IO
fgetc
Prototype: <span>extern int fputc (int __c, FILE *__stream);</span>
fputc
Prototype: <span>extern int fgetc (FILE *__stream);</span>
2. String IO
2.1 Standard IO
fgets
Prototype: <span>fgets (char *__restrict __s, int __n, FILE *__restrict __stream);</span> Note that to read data from the keyboard, use stdin. Note that <span>it will read along with \n</span>.
puts
Prototype: <span>extern int puts (const char *__s);</span> Outputs string s to the console.
2.2 File IO
fgets
Similar to the standard output above, but replaces the console’s <span>stdin</span> with the file pointer <span>fp</span>.
fputs
Prototype:<span>int fputs(const char *__restrict__ __s, FILE *__restrict__ __stream);</span> Inputs string s into the file pointer fp.
3. Formatted Strings
The core point: various data types can be converted to
<span>%s</span>
3.1 Standard IO
printf
Prototype: <span>printf (const char *__restrict __fmt, ...);</span>
Prints formatted strings to standard output until the first space character (<span>'\0'</span>) is encountered;
scanf
Prototype: <span>extern int scanf (const char *__restrict __format, ...);</span>
Receives strings from keyboard input until a space (<span>space</span>, <span>tab</span>, <span>newline</span>);
3.2 File IO
fprintf
Prototype: <span>fprintf (FILE *__restrict __stream, const char *__restrict __fmt, ...);</span>
Writes formatted strings to a file.
fscanf
Prototype: <span>extern int fscanf (FILE *__restrict __stream,const char *__restrict __format, ...);</span>
Reads formatted strings from a file.
3.3 Memory Character IO
sprintf
Commonly used to convert int type to char* type, this is natural.
Prototype: <span>extern int sprintf (char *__restrict __s,const char *__restrict __format, ...);</span>
sprintf(dest,”%s”,”ddddd”)//<span>Assignment direction <-</span>, writes the formatted character to dest. Of course, sprintf(dest,”ddddd”) is also correct.
sscanf
Prototype: <span>extern int sscanf (const char *__restrict __s, const char *__restrict __format, ...);</span>
sscanf(dest, “%s”, src); // <span>Assignment direction -></span>, reads formatted characters from dest and assigns them to src.
4. Binary IO
File IO
fread
Prototype: <span>fread (void *__restrict __ptr, size_t __size, size_t __n,FILE *__restrict __stream);</span>
Reads __n blocks of memory content of size __size from the address pointed to by __ptr.
fwrite
Prototype: <span>extern size_t fwrite (const void *__restrict __ptr, size_t __size,size_t __n, FILE *__restrict __s);</span>
Stores __n blocks of memory content of size __size from the address pointed to by __ptr into a file.
Test Document
Code
#include <stdio.h>
#define CHAR_IO_
#define CHARS_IO_
#define FOMAT_CHAR_IO_
#define BINARY_CHAR_IO_
int main()
{
#ifdef CHAR_IO_
printf("TEST char_io\n\n");
{
char ch;
ch = getchar();
putchar(ch);
printf("\n");
}
{
FILE *fp;
fp = fopen("/home/eyk/桌面/MCU/2.知识卡片/字符串/char_io.txt", "w+");
if (fp == NULL)
{
perror("fopen failed");
}
else
{
fputc('a', fp);
}
char ch;
rewind(fp); // 记得一定要置位为0
while ((ch = fgetc(fp)) != EOF)
{
putchar(ch);
}
fclose(fp);
}
#endif
#ifdef CHARS_IO_
printf("TEST chars_io\n\n");
{
char dest[20] = {0};
fgets(dest, 20, stdin); // 会连着读取换行符
printf("%s\n", dest);
puts("hello world");
}
printf("TEST FILE_IO\n\n");
{
FILE *fp = fopen("/home/eyk/桌面/MCU/2.知识卡片/字符串/char_io.txt", "w+");
if (fp == NULL)
{
perror("fopen failed");
}
else
{
fputs("hello world", fp);
rewind(fp);
char dest[20] = {0};
fgets(dest, 20, fp);
printf("%s\n", dest);
}
}
#endif
#ifdef FOMAT_CHAR_IO_
printf("TEST FOMAT_CHAR_IO\n\n");
{
char dest[20] = {0};
scanf("%s", dest);
dest[3] = '\0';
printf("%s\n", dest);
}
printf("TEST FILE_IO\n\n");
{
FILE *fp = fopen("/home/eyk/桌面/MCU/2.知识卡片/字符串/char_io.txt", "w+");
if (fp == NULL)
{
perror("fopen failed");
}
else
{
char dest[20] = {0};
fprintf(fp, "%s", "hello world");
rewind(fp); // 记得一定要置位为0
fscanf(fp, "%s", dest);
printf("%s\n", dest);
}
}
printf("TEST FOMAT_CHAR_IO\n\n");
{
char dest[20] = {0};
char src[20] = {0};
int a = 100;
// 假设给dest赋一个初始值,方便测试
sprintf(dest, "hello"); // 赋值方向<-
// 从dest读取内容到src
sscanf(dest, "%s", src); // 赋值方向->
printf("%s\n", src);
// 将dest和a的值格式化到dest中
sprintf(dest, "%s_%d\n", src, a); // 赋值方向<-
printf("%s\n", dest);
}
#endif
#ifdef BINARY_CHAR_IO_
printf("TEST BINARY_CHAR_IO\n\n");
{
char dest[20] = {0};
sprintf(dest, "hello\nworld"); // 多用函数来实现赋值!
FILE *fp = fopen("/home/eyk/桌面/MCU/2.知识卡片/字符串/char_io.txt", "w+");
if (fp == NULL)
{
perror("fopen failed");
}
else
{
fwrite(dest, sizeof(char), 11, fp);
rewind(fp);
char dest1[20] = {0};
fread(dest1, sizeof(char), 11, fp);
printf("%s\n", dest1);
}
}
#endif
}
Results
TEST char_io
4444
4
aTEST chars_io
444
hello world
TEST FILE_IO
hello world
TEST FOMAT_CHAR_IO
44445555
444
TEST FILE_IO
hello
TEST FOMAT_CHAR_IO
hello
hello_100
TEST BINARY_CHAR_IO
hello
world