标准IO总结

c语言中的标准IO以及文件IO 阅读详情

目录

标准IO总结

一、标准IO(符合ANSI C的标准)

1、流的缓冲类型

①、全缓冲:缓冲区满才输出

②、行缓冲:遇到换行符输出

③、无缓冲:不对IO操作进行缓冲

2、流的打开

函数原型:

2、流的关闭

函数原型:

3、错误处理

函数原型

函数原型

4、流的读写

按字节输入、输出

①、输入

函数原型:

②、输出

函数原型:

按行输入、输出

①、输入

函数原型1:

函数原型2:

②、输出

函数原型1:

函数原型2:

以指定大小单位读写文件

读

函数原型1:

写

函数原型:

5、流的定位

每次读写会改变流的位置,因此为了更好的操作,可以对流进行定位操作。

移动流的位置

函数原型:

得到流的位置

函数原型:

6、格式化的输入、输出

①、输入

函数原型1:

函数原型2:

函数原型3:

②、输出

函数原型1:

函数原型2:

函数原型3:


标准IO总结

一、标准IO(符合ANSI C的标准)

1、流的缓冲类型

①、全缓冲:缓冲区满才输出
②、行缓冲:遇到换行符输出
③、无缓冲:不对IO操作进行缓冲

2、流的打开

使用标准IO打开文件

函数原型:
FILE *  fopen(const char * path, const char * mode);

参数:

path:要代开文件的路径及文件名

mode:打开方式,具体有以下几种:

r 或 rb:打开只读文件,注意文件必须存在。

r+ 或 r+b:打开可读可写文件,注意文件也必须存在。

w 或 wb:打开只写文件,它会自己创建文件,如果文件已经存在,他会擦除已经写入的内容。

w+ 或 w+b:打开可写可读文件,它会自己创建文件,如果文件已经存在,他会擦除已经写入的内容。

a 或 ab:以附加内容的方式打开可写文件,就是写入的数据会被加到文件的末尾,原来的文件会被保留,如果文件不存在会创建文 件。

a+ 或 a+b:以附加内容的方式打开可读可写文件,就是写入的数据会被加到文件的末尾,原来的文件会被保留,如果文件不存在会 创建文件。

返回值

成功时返回一个指向 FILE 类型的指针,表示文件流。

失败时返回 NULL,可以通过 errno 获取错误原因。

示例代码

#include <stdio.h>
​
int main() {
    FILE *file = fopen("example.txt", "w");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }
​
    fprintf(file, "Hello, World!\n");
    fclose(file);
​
    return 0;
}

2、流的关闭

函数原型:
int fclose(FILE *stream);

参数

stream:指向 FILE 类型的指针,表示要关闭的文件流。这个指针是通过 fopen 或其他文件打开函数(如 tmpfile、fopen_s 等)返回的。

返回值

成功时返回 0。

失败时返回 EOF(通常定义为 -1),可以通过 errno 获取错误原因。

3、错误处理

下面函数打印一条错误消息,该消息包含了当前程序的错误状态。

函数原型
void perror(const char *s);

参数

s:一个指向字符串的指针,该字符串将被打印在错误消息之前。如果传入 NULL,则不会打印用户自定义的字符串,直接打印错误信息。

示例代码

#include <stdio.h>
#include <errno.h>
​
int main() {
    FILE *file = fopen("nonexistent_file.txt", "r");
    if (file == NULL) {
        perror("Error opening file");  // 打印错误信息
        return 1;
    }
​
    fclose(file);
    return 0;
}

如果文件 "nonexistent_file.txt" 不存在,程序将输出类似以下内容:

Error opening file: No such file or directory

下面函数将错误代码转换为对应的错误信息字符串

函数原型
char *strerror(int errnum);

参数

errnum:错误代码,通常是全局变量 errno 的值。

返回值

返回一个指向错误信息字符串的指针,该字符串描述了错误代码 errnum 对应的错误。需要注意的是,返回的字符串是由 strerror 内部管理的,程序不应修改该字符串。

示例代码

#include <stdio.h>
#include <string.h>
#include <errno.h>
​
int main() {
    FILE *file = fopen("nonexistent_file.txt", "r");
    if (file == NULL) {
        printf("Error: %s\n", strerror(errno));
    }
    return 0;
}

如果文件 "nonexistent_file.txt" 不存在,程序将输出类似以下内容:

Error: No such file or directory

4、流的读写

按字节输入、输出

①、输入

函数原型:
int getc (FILE * stream);//指定从流中读一个字符
int fgetc (FILE * stream);//指定从流中读一个字符
int getchar (void);//从stdin中读入一个字节

函数参数:

stream:要输入的文件流

返回值:

成功返回读取的字符

失败返回EOF

实例代码1:

#include <stdio.h>

int main() {
    FILE *file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }

    int ch;
    while ((ch = getc(file)) != EOF) {  // 逐字符读取
        putchar(ch);  // 将读取的字符打印到标准输出
    }

    if (fclose(file) != 0) {
        perror("Error closing file");
        return 1;
    }

    return 0;
}

实例代码2:

#include <stdio.h>

int main() {
    FILE *file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }

    int ch;
    while ((ch = fgetc(file)) != EOF) {  // 逐字符读取
        putchar(ch);  // 将读取的字符打印到标准输出
    }

    if (ferror(file)) {
        perror("Error reading file");
    }

    if (fclose(file) != 0) {
        perror("Error closing file");
        return 1;
    }

    return 0;
}

实例代码3:

#include <stdio.h>

int main() {
    int ch;
    printf("Enter some text (press Ctrl+D to end on Unix, Ctrl+Z on Windows):\n");

    while ((ch = getchar()) != EOF) {  // 逐字符读取
        putchar(ch);  // 将读取的字符打印到标准输出
    }

    if (ferror(stdin)) {
        perror("Error reading from stdin");
    }

    printf("\nEnd of input.\n");
    return 0;
}
②、输出

函数原型:
int putc (int c, FILE * stream);
int fputc (int c, FILE * stream);
int putchar (int c);

函数参数:

ch:要写入的字符。

stream:指向 FILE 对象的指针,标识要写入字符的流。

返回值:

成功返回写入的字符

失败返回EOF

实例代码1:

#include <stdio.h>

int main() {
    FILE *pFile;
    char c;

    pFile = fopen("alphabet.txt", "wt");
    for (c = 'A'; c <= 'Z'; c++) {
        putc(c, pFile);
    }
    fclose(pFile);
    return 0;
}

实例代码2:

#include <stdio.h>

int main() {
    FILE *pFile;
    char c;

    pFile = fopen("alphabet.txt", "wt");
    if (pFile == NULL) {
        printf("文件打开失败!");
        return -1;
    }
    for (c = 'A'; c <= 'Z'; c++) {
        fputc(c, pFile);
    }
    fclose(pFile);
    return 0;
}

实例代码3:

#include <stdio.h>

int main() {
    char c;

    for (c = 'A'; c <= 'Z'; c++) {
        putchar(c);
    }
    putchar('\n'); // 写入换行符
    return 0;
}

按行输入、输出

①、输入

函数原型1:
char* gets(char* s);//在C11被移除了

参数

s:指向字符数组的指针,用于存储从标准输入读取的字符串。

返回值

成功时返回参数 s,即存储输入字符串的数组的首地址。

如果发生读取错误或到达文件末尾(EOF),返回 NULL。

  • 严重安全隐患:gets 不检查目标数组的大小,容易导致缓冲区溢出。如果输入的字符串长度超过了目标数组的大小,会导致内存破坏,从而引发安全漏洞。

示例代码

#include <stdio.h>

int main() {
    char buffer[10];
    printf("请输入一行文本:");
    gets(buffer);  // 不安全的函数
    printf("您输入的内容是:%s\n", buffer);
    return 0;
}

注意:如果输入的字符串长度超过 buffer 的大小(在这个例子中是 9 个字符,因为最后一个位置用于存储字符串结束符 \0),会导致缓冲区溢出。

函数原型2:

fgets 是 gets 的安全替代品,它允许指定目标缓冲区的大小,从而避免缓冲区溢出。

char* fgets(char* s, int size, FILE* stream);

参数:

s:目标字符数组。

size:目标数组的最大大小。

stream:输入流,默认为 stdin。

返回值:

成功时返回参数 s。

如果发生读取错误或到达文件末尾,返回 NULL。

示例代码:

#include <stdio.h>

int main() {
    char buffer[10];
    printf("请输入一行文本:");
    if (fgets(buffer, sizeof(buffer), stdin)) {
        // 去掉换行符
        buffer[strcspn(buffer, "\n")] = '\0';
        printf("您输入的内容是:%s\n", buffer);
    }
    return 0;
}

注意:fgets不能保证每次都能读出一行

②、输出

函数原型1:
int puts(const char *s);

参数

s:指向要输出的字符串的指针。该字符串必须以空字符(\0)结尾。

返回值

成功时返回非负值(通常是输出的字符数)。

如果发生输出错误,返回 EOF(通常定义为 -1)。

  • puts 会将字符串输出到标准输出流 stdout,并在字符串末尾自动添加一个换行符。

示例代码

#include <stdio.h>

int main() {
    const char *str1 = "Hello, World!";
    const char *str2 = "This is a test.";

    puts(str1); // 输出 "Hello, World!" 并换行
    puts(str2); // 输出 "This is a test." 并换行

    return 0;
}

输出结果:

Hello, World!
This is a test.

函数原型2:
int fputs(const char *s, FILE *stream);

参数

s:指向要写入的字符串的指针。该字符串必须以空字符(\0)结尾。

stream:指向 FILE 对象的指针,标识要写入的文件流。

返回值

成功时返回非负值(通常是 0 或 1,具体值取决于实现)。

如果发生写入错误,返回 EOF(通常定义为 -1)。

  • fputs 将字符串写入到指定的文件流中,不会自动添加换行符。

示例代码:

#include <stdio.h>

int main() {
    FILE *file;
    const char *str1 = "Hello, World!";
    const char *str2 = "This is a test.";

    // 打开文件用于写入
    file = fopen("output.txt", "w");
    if (file == NULL) {
        printf("文件打开失败!");
        return -1;
    }

    // 写入字符串
    fputs(str1, file);
    fputs("\n", file); // 显式添加换行符
    fputs(str2, file);
    fputs("\n", file); // 显式添加换行符

    // 关闭文件
    fclose(file);

    return 0;
}

运行后,output.txt 文件的内容为:

Hello, World!
This is a test.

以指定大小单位读写文件

读

函数原型1:
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);

参数

ptr:指向存储读取数据的缓冲区的指针。

size:每个数据项的大小(以字节为单位)。

count:要读取的数据项的数量。

stream:指向 FILE 对象的指针,标识要从中读取数据的文件流。

返回值

成功时返回实际读取的数据项的数量。

如果到达文件末尾(EOF)或发生读取错误,返回值会小于 count。

如果返回值为 0,可能是到达文件末尾或发生错误。可以通过 feof 和 ferror 函数来区分这两种情况。

  • fread 是一个通用的文件读取函数,可以读取任意类型的数据。

  • 它支持二进制文件和文本文件,但通常用于二进制文件,因为文本文件的读取通常更适合使用 fgets 等函数。

  • fread 会根据指定的 size 和 count 参数,从文件流中读取数据,并将其存储到指定的缓冲区中。

  • 如果文件流中的数据不足,fread 会读取尽可能多的数据,返回值会小于 count。

示例代码1:

示例 1:读取文本文件

假设有一个文本文件 data.txt,内容如下:

Hello, World!
This is a test.
#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *file;
    char buffer[100];

    // 打开文件用于读取
    file = fopen("data.txt", "r");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 读取数据
    size_t bytesRead = fread(buffer, sizeof(char), sizeof(buffer) - 1, file);
    buffer[bytesRead] = '\0'; // 确保字符串以空字符结尾

    // 输出读取的内容
    printf("读取的内容:\n%s\n", buffer);

    // 关闭文件
    fclose(file);

    return 0;
}

输出结果:

读取的内容:
Hello, World!
This is a test.

示例代码2:读取二进制文件

假设有一个二进制文件 data.bin,包含一些整数数据。

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *file;
    int buffer[10];
    size_t bytesRead;

    // 打开文件用于读取
    file = fopen("data.bin", "rb");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 读取数据
    bytesRead = fread(buffer, sizeof(int), 10, file);

    // 输出读取的内容
    printf("读取了 %zu 个整数:\n", bytesRead);
    for (size_t i = 0; i < bytesRead; i++) {
        printf("%d ", buffer[i]);
    }
    printf("\n");

    // 关闭文件
    fclose(file);

    return 0;
}
写

函数原型:
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);

参数

ptr:指向要写入的数据的指针。

size:每个数据项的大小(以字节为单位)。

count:要写入的数据项的数量。

stream:指向 FILE 对象的指针,标识要写入数据的文件流。

返回值

成功时返回实际写入的数据项的数量。

如果发生写入错误,返回值会小于 count。

如果返回值为 0,可能是到达文件末尾或发生错误。可以通过 ferror 函数来检查是否发生错误。

  • fwrite 是一个通用的文件写入函数,可以写入任意类型的数据。

  • 它支持二进制文件和文本文件,但通常用于二进制文件,因为文本文件的写入通常更适合使用 fprintf 或 fputs 等函数。

  • fwrite 会根据指定的 size 和 count 参数,将数据从指定的缓冲区写入到文件流中。

  • 如果文件流中的空间不足,fwrite 会写入尽可能多的数据,返回值会小于 count。

示例代码1:

示例 1:写入文本数据

假设要将一个字符串写入到文本文件 output.txt 中。

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *file;
    const char *str = "Hello, World!";

    // 打开文件用于写入
    file = fopen("output.txt", "w");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 写入数据
    size_t bytesWritten = fwrite(str, sizeof(char), strlen(str), file);

    // 检查写入是否成功
    if (bytesWritten != strlen(str)) {
        perror("写入文件时发生错误");
    }

    // 关闭文件
    fclose(file);

    return 0;
}

运行后,output.txt 文件的内容为:

Hello, World!

代码示例 2:写入二进制数据

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *file;
    int data[] = {1, 2, 3, 4, 5};
    size_t count = sizeof(data) / sizeof(data[0]);

    // 打开文件用于写入
    file = fopen("data.bin", "wb");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 写入数据
    size_t itemsWritten = fwrite(data, sizeof(int), count, file);

    // 检查写入是否成功
    if (itemsWritten != count) {
        perror("写入文件时发生错误");
    }

    // 关闭文件
    fclose(file);

    return 0;
}

5、流的定位

每次读写会改变流的位置,因此为了更好的操作,可以对流进行定位操作。
移动流的位置

函数原型:
int fseek(FILE *stream, long offset, int whence);

参数:

stream:指向 FILE 对象的指针,标识要操作的文件流。

offset:偏移量,表示要移动的字节数。

whence:指定偏移量的基准位置,可以取以下值:

  • SEEK_SET:文件开头(从文件开头开始计算偏移量)。

  • SEEK_CUR:当前位置(从当前位置开始计算偏移量)。

  • SEEK_END:文件末尾(从文件末尾开始计算偏移量)。

返回值:

成功时返回 0。

如果发生错误,返回非零值(通常为 -1)。

  • 它通常用于二进制文件,因为文本文件的读写操作可能会受到换行符等特殊字符的影响。

  • 在文本模式下使用 fseek 时,只有当偏移量为零且基准位置为 SEEK_SET 或 SEEK_END 时,才能保证行为是定义良好的。

  • 在二进制模式下,fseek 的行为是完全定义的,可以精确地移动文件指针。

示例代码1:

跳到文件开头

#include <stdio.h>

int main() {
    FILE *file;
    char buffer[100];

    file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 跳到文件开头
    if (fseek(file, 0, SEEK_SET) != 0) {
        perror("移动文件指针失败");
        fclose(file);
        return -1;
    }

    // 读取文件内容
    if (fgets(buffer, sizeof(buffer), file) != NULL) {
        printf("读取的内容:%s", buffer);
    }

    fclose(file);
    return 0;
}

实例代码2:

跳到文件末尾

#include <stdio.h>

int main() {
    FILE *file;
    long fileSize;

    file = fopen("example.txt", "rb");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 跳到文件末尾
    if (fseek(file, 0, SEEK_END) != 0) {
        perror("移动文件指针失败");
        fclose(file);
        return -1;
    }

    // 获取文件大小
    fileSize = ftell(file);
    printf("文件大小:%ld 字节\n", fileSize);

    fclose(file);
    return 0;
}

示例 代码3:

从当前位置移动

#include <stdio.h>

int main() {
    FILE *file;
    char buffer[100];

    file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 跳过前 10 个字节
    if (fseek(file, 10, SEEK_SET) != 0) {
        perror("移动文件指针失败");
        fclose(file);
        return -1;
    }

    // 从当前位置再跳过 5 个字节
    if (fseek(file, 5, SEEK_CUR) != 0) {
        perror("移动文件指针失败");
        fclose(file);
        return -1;
    }

    // 读取文件内容
    if (fgets(buffer, sizeof(buffer), file) != NULL) {
        printf("读取的内容:%s", buffer);
    }

    fclose(file);
    return 0;
}
得到流的位置

函数原型:
long ftell(FILE *stream);

参数:

stream:指向 FILE 对象的指针,标识要查询的文件流。

返回值:

成功时返回当前文件位置指示符的位置(以字节为单位)。

如果发生错误,返回 -1L(负一)。

  • ftell 返回的值表示从文件开头到当前文件位置指示符的距离(以字节为单位)。

  • 在二进制模式下,ftell 的返回值是精确的,可以直接用于文件定位。

  • 在文本模式下,ftell 的返回值可能不完全精确,因为文本模式下的文件操作会受到换行符等特殊字符的影响。

  • ftell 通常与 fseek 配合使用,用于定位文件中的特定位置。

示例代码1:

获取文件指针的当前位置

#include <stdio.h>

int main() {
    FILE *file;
    long position;

    file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 获取文件指针的当前位置
    position = ftell(file);
    if (position == -1L) {
        perror("获取文件位置失败");
        fclose(file);
        return -1;
    }

    printf("当前文件指针的位置:%ld 字节\n", position);

    fclose(file);
    return 0;
}

示例代码 2:

获取文件大小

#include <stdio.h>

int main() {
    FILE *file;
    long fileSize;

    file = fopen("example.txt", "rb");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 跳到文件末尾
    if (fseek(file, 0, SEEK_END) != 0) {
        perror("移动文件指针失败");
        fclose(file);
        return -1;
    }

    // 获取文件大小
    fileSize = ftell(file);
    if (fileSize == -1L) {
        perror("获取文件大小失败");
        fclose(file);
        return -1;
    }

    printf("文件大小:%ld 字节\n", fileSize);

    fclose(file);
    return 0;
}

示例 代码3:

读取文件内容并记录位置

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *file;
    char buffer[100];
    long position;

    file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 读取文件内容
    while (fgets(buffer, sizeof(buffer), file) != NULL) {
        // 获取当前文件指针的位置
        position = ftell(file);
        if (position == -1L) {
            perror("获取文件位置失败");
            fclose(file);
            return -1;
        }

        printf("读取的内容:%s", buffer);
        printf("当前文件指针的位置:%ld 字节\n", position);
    }

    fclose(file);
    return 0;
}

6、格式化的输入、输出

①、输入

函数原型1:
int scanf(const char *format, ...);

参数:

format:格式控制字符串,用于指定输入的格式。它包含格式说明符(如 %d、%s、%f 等)和普通字符。

... :可变参数列表,用于存储读取的数据。每个格式说明符对应一个变量的地址。

返回值:

成功时返回成功读取的输入项数量。

如果到达文件末尾(EOF)或发生输入错误,返回值会小于预期的输入项数量。

如果没有成功读取任何输入项,返回值可能为 0 或 EOF。

格式说明符:

scanf 使用格式说明符来指定输入的类型和格式。以下是一些常见的格式说明符:

  • %d:读取十进制整数。

  • %u:读取无符号十进制整数。

  • %f:读取浮点数。

  • %lf:读取双精度浮点数(double)。

  • %c:读取单个字符。

  • %s:读取字符串(以空字符 \0 结尾)。

  • %x 或 %X:读取十六进制整数。

  • %o:读取八进制整数。

  • %p:读取指针地址。

  • %[...]:读取字符集,直到遇到不在字符集中的字符为止。

示例 代码1:

读取整数和浮点数

#include <stdio.h>

int main() {
    int num1;
    float num2;

    printf("请输入一个整数和一个浮点数:");
    if (scanf("%d %f", &num1, &num2) == 2) {
        printf("整数:%d\n", num1);
        printf("浮点数:%f\n", num2);
    } else {
        printf("输入格式错误!\n");
    }

    return 0;
}

示例 代码2:

读取字符串

#include <stdio.h>

int main() {
    char str[100];

    printf("请输入一行文本:");
    if (scanf("%s", str)) {
        printf("您输入的内容:%s\n", str);
    } else {
        printf("输入失败!\n");
    }

    return 0;
}

示例代码 3:

读取多个数据类型

#include <stdio.h>

int main() {
    int age;
    float height;
    char name[100];

    printf("请输入您的姓名、年龄和身高:");
    if (scanf("%s %d %f", name, &age, &height) == 3) {//这个输入有讲究,需要使用空格来隔开输入
        printf("姓名:%s\n", name);
        printf("年龄:%d\n", age);
        printf("身高:%.2f\n", height);
    } else {
        printf("输入格式错误!\n");
    }

    return 0;
}

函数原型2:
int fscanf(FILE *stream, const char *format, ...);

参数:

stream:指向 FILE 对象的指针,标识要从中读取数据的文件流。

format:格式控制字符串,用于指定输入的格式。它包含格式说明符(如 %d、%s、%f 等)和普通字符。

... :可变参数列表,用于存储读取的数据。每个格式说明符对应一个变量的地址。

返回值:

成功时返回成功读取的输入项数量。

如果到达文件末尾(EOF)或发生输入错误,返回值会小于预期的输入项数量。

如果没有成功读取任何输入项,返回值可能为 0 或 EOF。

格式说明符:

fscanf 使用的格式说明符与 scanf 相同

示例 代码1:

从文件中读取整数和浮点数

假设有一个文件 data.txt,内容如下:

123 45.67
#include <stdio.h>

int main() {
    FILE *file;
    int num1;
    float num2;

    file = fopen("data.txt", "r");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 从文件中读取数据
    if (fscanf(file, "%d %f", &num1, &num2) == 2) {
        printf("整数:%d\n", num1);
        printf("浮点数:%f\n", num2);
    } else {
        printf("输入格式错误!\n");
    }

    fclose(file);
    return 0;
}

示例 代码2:

从文件中读取字符串

假设有一个文件 data.txt,内容如下:

Hello, World!
#include <stdio.h>

int main() {
    FILE *file;
    char str[100];

    file = fopen("data.txt", "r");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 从文件中读取字符串
    if (fscanf(file, "%s", str) == 1) {
        printf("读取的字符串:%s\n", str);
    } else {
        printf("输入失败!\n");
    }

    fclose(file);
    return 0;
}

示例代码3:

从文件中读取多行数据

假设有一个文件 data.txt,内容如下:

John 25
Alice 30
#include <stdio.h>

int main() {
    FILE *file;
    char name[100];
    int age;

    file = fopen("data.txt", "r");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 逐行读取数据
    while (fscanf(file, "%s %d", name, &age) == 2) {
        printf("姓名:%s,年龄:%d\n", name, age);
    }

    fclose(file);
    return 0;
}

函数原型3:
int sscanf(const char *str, const char *format, ...);

参数:

str:指向要解析的字符串的指针。

format:格式控制字符串,用于指定输入的格式。它包含格式说明符(如 %d、%s、%f 等)和普通字符。

... :可变参数列表,用于存储解析后的数据。每个格式说明符对应一个变量的地址。

返回值:

成功时返回成功读取的输入项数量。

如果没有成功读取任何输入项,返回值可能为 0。

如果输入字符串格式不匹配或发生错误,返回值会小于预期的输入项数量。

格式说明符:

sscanf 使用的格式说明符与 scanf 和 fscanf 相同

示例代码 1:

从字符串中读取整数和浮点数

假设有一个字符串 "123 45.67",需要从中提取整数和浮点数。

#include <stdio.h>

int main() {
    const char *str = "123 45.67";
    int num1;
    float num2;

    // 从字符串中读取数据
    if (sscanf(str, "%d %f", &num1, &num2) == 2) {
        printf("整数:%d\n", num1);
        printf("浮点数:%f\n", num2);
    } else {
        printf("输入格式错误!\n");
    }

    return 0;
}

示例 代码2:

从字符串中读取日期

假设有一个字符串 "2023-10-25",需要从中提取年、月、日。

#include <stdio.h>

int main() {
    const char *str = "2023-10-25";
    int year, month, day;

    // 从字符串中读取日期
    if (sscanf(str, "%d-%d-%d", &year, &month, &day) == 3) {
        printf("年:%d\n", year);
        printf("月:%d\n", month);
        printf("日:%d\n", day);
    } else {
        printf("输入格式错误!\n");
    }

    return 0;
}

示例代码 3:

从字符串中读取多组数据

假设有一个字符串 "John 25 Alice 30",需要从中提取多组姓名和年龄。

#include <stdio.h>

int main() {
    const char *str = "John 25 Alice 30";
    char name1[100], name2[100];
    int age1, age2;

    // 从字符串中读取多组数据
    if (sscanf(str, "%s %d %s %d", name1, &age1, name2, &age2) == 4) {
        printf("姓名:%s,年龄:%d\n", name1, age1);
        printf("姓名:%s,年龄:%d\n", name2, age2);
    } else {
        printf("输入格式错误!\n");
    }

    return 0;
}
②、输出

函数原型1:
int printf(const char *format, ...);

参数:

format:格式控制字符串,用于指定输出的格式。它包含普通字符和格式说明符。

... :可变参数列表,用于提供要输出的数据。每个格式说明符对应一个参数。

返回值:

成功时返回输出的字符数量(不包括末尾的换行符)。

如果发生错误,返回负值。

格式说明符:

printf 使用格式说明符来指定输出的类型和格式。以下是一些常见的格式说明符:

  • %d 或 %i:输出十进制整数。

  • %u:输出无符号十进制整数。

  • %f:输出浮点数(默认为双精度)。

  • %lf:输出双精度浮点数(与 %f 等效)。

  • %c:输出单个字符。

  • %s:输出字符串。

  • %x 或 %X:以十六进制形式输出整数(%x 小写,%X 大写)。

  • %o:以八进制形式输出整数。

  • %p:输出指针地址。

  • %%:输出一个百分号(%)。

格式修饰符:

printf 还支持格式修饰符,用于控制输出的宽度、精度、对齐方式等:

  • 宽度:%5d 表示输出宽度为 5 个字符,不足部分用空格填充。

  • 左对齐:%-5d 表示左对齐,宽度为 5 个字符。

  • 精度:%.2f 表示浮点数保留两位小数。

  • 填充字符:%05d 表示用 0 填充,宽度为 5 个字符。

示例 代码1:

输出整数和浮点数

#include <stdio.h>

int main() {
    int num1 = 123;
    float num2 = 45.67;

    printf("整数:%d\n", num1);
    printf("浮点数:%.2f\n", num2);

    return 0;
}

示例代码 2:

输出字符串和字符

#include <stdio.h>

int main() {
    char str[] = "Hello, World!";
    char ch = 'A';

    printf("字符串:%s\n", str);
    printf("字符:%c\n", ch);

    return 0;
}

示例代码 3:

控制输出格式

#include <stdio.h>

int main() {
    int num1 = 123;
    float num2 = 45.67;

    printf("整数:%5d\n", num1);  // 输出宽度为 5
    printf("浮点数:%-10.2f\n", num2);  // 左对齐,宽度为 10,保留两位小数
    printf("十六进制:%X\n", num1);  // 输出十六进制

    return 0;
}

示例 代码4:

输出指针地址

#include <stdio.h>

int main() {
    int num = 123;
    int *ptr = &num;

    printf("指针地址:%p\n", ptr);

    return 0;
}

函数原型2:
int fprintf(FILE *stream, const char *format, ...);

参数:

stream:指向 FILE 对象的指针,标识要输出到的文件流。

format:格式控制字符串,用于指定输出的格式。它包含普通字符和格式说明符。

... :可变参数列表,用于提供要输出的数据。每个格式说明符对应一个参数。

返回值:

成功时返回输出的字符数量(不包括末尾的换行符)。

如果发生错误,返回负值。

格式说明符:

fprintf 使用的格式说明符与 printf 相同

格式修饰符:

fprintf 也支持格式修饰符与 printf 相同

示例 代码1:

向文件输出整数和浮点数

假设要将一些数据写入到文件 output.txt 中。

#include <stdio.h>

int main() {
    FILE *file;
    int num1 = 123;
    float num2 = 45.67;

    file = fopen("output.txt", "w");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 向文件输出数据
    fprintf(file, "整数:%d\n", num1);
    fprintf(file, "浮点数:%.2f\n", num2);

    fclose(file);
    return 0;
}

运行后,output.txt 文件的内容为:

整数:123
浮点数:45.67

示例代码2:

向文件输出字符串和字符

假设要将一些文本数据写入到文件 output.txt 中。

#include <stdio.h>

int main() {
    FILE *file;
    char str[] = "Hello, World!";
    char ch = 'A';

    file = fopen("output.txt", "w");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 向文件输出数据
    fprintf(file, "字符串:%s\n", str);
    fprintf(file, "字符:%c\n", ch);

    fclose(file);
    return 0;
}

运行后,output.txt 文件的内容为:

字符串:Hello, World!
字符:A

示例 代码3:

控制输出格式

假设要将一些格式化的数据写入到文件 output.txt 中。

#include <stdio.h>

int main() {
    FILE *file;
    int num1 = 123;
    float num2 = 45.67;

    file = fopen("output.txt", "w");
    if (file == NULL) {
        perror("文件打开失败");
        return -1;
    }

    // 向文件输出格式化数据
    fprintf(file, "整数:%5d\n", num1);  // 输出宽度为 5
    fprintf(file, "浮点数:%-10.2f\n", num2);  // 左对齐,宽度为 10,保留两位小数
    fprintf(file, "十六进制:%X\n", num1);  // 输出十六进制

    fclose(file);
    return 0;
}

运行后,output.txt 文件的内容为:

整数:  123
浮点数:45.67     
十六进制:7B

函数原型3:
int sprintf(char *str, const char *format, ...);

参数:

str:指向目标字符数组的指针,格式化后的字符串将存储在这个数组中。

format:格式控制字符串,用于指定输出的格式。它包含普通字符和格式说明符。

... :可变参数列表,提供要格式化的数据。每个格式说明符对应一个参数。

返回值:

成功时返回写入的字符数量(不包括字符串结束符 \0)。

如果发生错误,返回负值。

格式说明符:

sprintf 使用的格式说明符与 printf 和 fprintf 相同

示例代码1:

将整数和浮点数格式化为字符串

#include <stdio.h>

int main() {
    char buffer[100];
    int num1 = 123;
    float num2 = 45.67;

    // 将数据格式化为字符串
    int count = sprintf(buffer, "整数:%d,浮点数:%.2f", num1, num2);

    printf("格式化后的字符串:%s\n", buffer);
    printf("写入的字符数量:%d\n", count);

    return 0;
}

输出结果:

格式化后的字符串:整数:123,浮点数:45.67
写入的字符数量:22

示例代码 2:

动态生成日志信息

#include <stdio.h>

int main() {
    char buffer[100];
    char logLevel[] = "ERROR";
    char message[] = "File not found";

    // 动态生成日志信息
    sprintf(buffer, "[%s] %s", logLevel, message);

    printf("日志信息:%s\n", buffer);

    return 0;
}

输出结果:

日志信息:[ERROR] File not found

示例代码3:

格式化日期和时间

#include <stdio.h>

int main() {
    char buffer[100];
    int year = 2023;
    int month = 10;
    int day = 25;

    // 格式化日期
    sprintf(buffer, "今天的日期是:%04d-%02d-%02d", year, month, day);

    printf("格式化后的日期:%s\n", buffer);

    return 0;
}

输出结果:

格式化后的日期:2023-10-25

参考资源:https://download.csdn.net/download/2403_82436914/90610803?spm=1001.2014.3001.5503

标准IO与文件IO linux下文件操作包含下面4个头文件: 阅读详情

相关推荐

Mac 环境配置jdk、Maven

3、终端打开配置jdk时候建好的脚本文件: open -e .bash_profile。4、查看maven是否安装成功和系统能不能识别maven/mvn命令:⬇️。输入⬇️并保存: 其中第一行JAVA_HOME替换为自己下的jdk路径。,安装编译好的二进制版本,具体安装zip还是tar.gz我看的。5、查看jdk是否安装成功和系统能不能识别java命令:⬇️。至此,我的Mac系统的环境配置jdk、Maven完成!然后就发现我的maven命令还是没作用,不识别,下载后直接安装即可,很快,点几下就OK了。

weixin_42416791的博客 4336

嵌入式(标准IO)

标准IO

afddasfa的博客 604

王珊数据库系统概论第5版视频教材

目录 隐藏 说明:本课程共包括1种电子书、84个高清视频(共68课时)、1种纸质书(赠品)。 网授课程 王珊《数据库系统概论》(第5版)网授精讲班【共68课时】 序号 名称 课时 1 第1章 绪 论(1) 00:32:25 2 第1章 绪 论(2) 00:17:03 3 第1章 绪 论(3) 00:50:19 4 第1章 绪 论(4) 00:20:37 5 第1章 绪 论(5) 00:24:47 6 第2章 关系数据库(1) 00:47:23 7 第2章 关系数据库(2) 00:14:48 8 第2章 关系

mrtaoy96的博客 1135

标准IO(介绍以及学习)

什么是标准IO?缓冲机制又是什么,标准IO的函数接口有哪些

m0_74761015的博客 2044

香橙派5使用RK3588S内置NPU加速yolov5推理,实时识别数字达到50fps

香橙派5采用了RK3588S,内置的NPU达到了6Tops的算力,博主这里记录一下自己的踩坑过程,好不容易做出来的不能以后忘记了(手动狗头)。这里博主还在B站上发布了效果视频,大家感兴趣的话可以看一下。其中解决了先验框标注位置不对,或者出现非常多的框的问题

weixin_51651698的博客 2万+

QT使用高精度定时器

精度相对第二种方法高许多。

ljjjjjjjjjjj的博客 4092

标准IO(库函数)

它的作用是将格式化的数据按照指定的格式写入到一个字符串中,而不是输出到屏幕上,它可以格式化数据,也可以组合两个字符串。作用:向指定流中输出单个字符,其中,c是要写入文件的字符的ASCII码值,stream是一个指向已打开文件的指针。sprintf函数将格式化后的字符串写入到str指向的字符数组中,并返回写入的字符数(不包括终止符\0)。fgets函数返回一个指向str的指针,如果成功读取到字符串,则返回str的值;其中,filename是一个字符串,表示要打开的文件的路径和名称;

qq_53090814的博客 646

随机截距交叉滞后模型RI-CLPM:原理、Mplus实现与结果解读

纵向面板数据分析中,传统交叉滞后模型(CLPM)常被用于探索变量间的时序关系,但其估计结果可能混淆了个体间稳定差异与个体内短期波动,导致交叉滞后路径出现偏差。随机截距交叉滞后模型(RI-CLPM)通过引入随机截距因子,将个体特质层面的差异与个体内动态过程分离,从而提供更纯净的个体内效应估计。该模型在组织心理学、发展心理学、成瘾行为等研究领域迅速普及,并成为顶级期刊审稿时常见的稳健性检验要求。本文从原理出发,系统讲解RI-CLPM的模型构建、识别条件、Mplus实操代码、输出解读及常见陷阱,并结合协变量处理、

weixin_33525298的博客 251

标准IO(基础知识学习)

关于标准IO的基本概念,缓存机制,行缓存,缓存区的刷新与缓存区大小的测试

m0_68210771的博客 1977

SAP SD模块进阶:VA31和VA01底层竟是同一个BAPI?揭秘销售单据创建的统一逻辑

本文深入解析SAP SD模块中VA31和VA01的底层统一架构设计,揭示两者如何通过同一个BAPI `SD_SALESDOCUMENT_CREATE`实现销售单据创建。通过ABAP调试和参数化设计分析,展示了SAP如何利用单据类型(doc_type)等关键字段实现业务逻辑复用,为开发者提供配置化设计的重要启示。

weixin_30561177的博客 240

【数据集】2019年中国1km格网河网密度数据集

中国1km格网河网密度数据集

WW、forever的博客 1336

标准 IO

在每一个操作系统下面,对文件的管理和接口都是不一样的Linux:open/close/read/write/lseek... Linux的系统IOAPP------>进程文件表项的下标(文件描述符)----->struct file *------>struct file ----->struct inode ----->硬件同一个文件,在不同的操作系统下面,操作文件的方法和代码可能不一样。

qq_68915288的博客 1341

RH850 GreenHillSoftware Install

IDE一次链接到一个Compiler/Green Hills Debug Probe安装目录。如果您安装了IDE、编译器和绿山调试探测器软件,安装程序会将安装链接在一起。如果您只使用Advanced Install选项安装IDE,那么当您第一次启动它时,IDE会提示您链接到编译器和绿山调试探针安装*。如果您使用Advanced Install选项只安装编译器和绿山调试探针软件,安装程序会提示您将IDE的安装链接到新的编译器和绿山调试探针安装。

舊梦的博客 1204

【IO】什么是IO、标准IO、文件IO

IO是计算机中的输入/输出(Input/Output)的简称,指的是之间进行数据交换的过程。输入是指将外部数据传输到计算机系统中,输出是指将计算机系统中的数据传输到外部设备中。在计算机中,输入可以来自多种来源,如键盘、鼠标、触摸屏、传感器等。输出可以发送到显示器、打印机、扬声器、存储设备等。IO操作是计算机系统中的重要组成部分,它使计算机能够与用户交互,接收用户的输入,并将计算结果输出给用户。通过IO操作,计算机可以读取外部数据、存储数据、显示信息、传输数据等。

m0_56844552的博客 5647

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【IO操作】标准IO和文件IO

主要介绍了标准 I/O 和文件 I/O 的区别,以及关于这两种 I/O 操作的详细介绍。标准 I/O 是基于 C 语言的库函数,而文件 I/O 是基于 Linux 系统调用的操作。文章分析了它们的区别,包括在跨平台性、系统调用频率以及文件描述符和文件指针等方面的不同。此外,文章总结了标准 I/O 和文件 I/O 中常用的函数、参数、返回值和常见用法,并提供了示例代码以便加深理解。

Atcxr的博客 2245

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

IO——标准IO

注:当a+的方式打开文件时,写只能在末尾进行追加,定位操作是无法改变写的位置,但是可以改变读的位置。a+:读和追加,文件不存在创建,存在追加,读文件流定位到文件开头,写文件流定位到文件末尾。参数: ptr :是一个指针,是存放数据的存储空间的起始地址,用来存放读取元素。a:追加(在末尾写),文件不存在创建,存在追加,文件流定位到文件末尾。参数: ptr :是一个指针,保存要输出数据的空间的地址。r+:可读可写,当文件不存在时报错,文件流定位到文件开头。r:只读,当文件不存在时报错,文件流定位到文件开头。

ka1es的博客 2216

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Linux中的系统IO与标准IO

一、系统IO与标准IO的区别 什么是系统IO与标准IO:(IO为Input/Output,即输入/输出接口) 系统IO:由操作系统直接提供的接口函数 标准IO:由标准C库(第三方库)提供的接口函数(通过封装操作系统提供的系统IO,再给用户使用) 系统IO和标准IO的主要区别: 系统IO:不带缓冲机制,系统IO可以操作普通文件与驱动文件 标准IO:带缓冲机制,标准IO只可以操作普通...

不吃鱼的猫的博客 6976

io学习----->标准io

以读写(追加)的方式打开文件(写入到文件的结尾)如果文件不存在则创建文件,如果文件存在则流指针指向文件的结尾。以追加的方式打开文件(写入到文件的结尾)如果文件不存在则创建文件,如果文件存在则流指针指向文件的结尾。以读写的方式打开文件. ,流指针指向文件的起始地址,如果文件存在则打开成功,不存在则打开失败。以读写的方式打开文件,如果文件不存在则创建文件,如果文件存在则清空文件。以写的方式打开文件,如果文件不存在则创建文件,如果文件存在则清空文件。fputc:输出的函数,对于文件,就是写入的意思。

qq_66012182的博客 2171

文件IO、标准IO的区别及其效率

系统IO:Unix/Linux下的系统文件IO,即文件访问机制不经过操作系统内核的缓存,数据直接在磁盘和应用程序地址空间进行传输。 标准IO:带缓存的IO,又称为标准IO(C标准库中提供了标准IO库,即stdio),它实现了跨平台的用户缓存解决方案。 文件IO 和 标准IO的概念 【文件I/O】 文件I/O是操作系统封装了一系列open、close、write、read等API函数构成的一套用来读、写文件的接口供应用程序使用,通过这些接口可以实现对文件的读写操作,但是效率并不是最...

llzhang_fly的博客 6750

标准IO和文件IO

简述 对文件进行操作,有文件IO和标准IO两种 标准IO: 采用库函数的方式对文件进行读写操作(对文件读写的函数接口出自于库)stdio.h 文件IO:采用系统调用的方式对文件进行读写操作(对文件的读写操作功能有内核提供),并且不带缓存, 系统调用:内核提供的一个接口层,用用程序通过此接口可以实现内核为应用程序提供的各种功能 系统调用的流程: 封装函数 -- 系统调...

hanfs390的博客 854

标准IO

1.标准IO和系统IO的区别 .1标准IO总是调用系统IO来完成自己的功能 系统IO:每个操作系统都有自己的IO方式 windows: openfile->内核->硬件 linux: open->内核->硬件 标准IO: windows: fopen->openfile->内核->硬件 linux: fopen-&...

weixin_40224996的博客 245

标准IO与系统IO的区别

1.系统IO操作文件时是无缓冲输入,一般用于操作字符设备文件(LCD, LED, BEEP ...,数据需 要实时刷新) 标准IO操作文件时是有缓冲输入,一般用于操作普通文件(.txt, .jpg...) 2.系统IO是Linux操作系统提供函数接口 标准IO标准C语言库函数提供的 系统IO的API接口有:open read write close lseek ...

Allllin的博客 5270

IO之标准IO

IO之标准IO

qq_57018268的博客 660

文件IO与标准IO总结

标准 IO文件IO概念C库中定义的一组用于输入输出的函数posix中定义的一组输入输出的函数特点有缓冲机制,减少系统调用,提高效率无缓冲机制围绕流进行操作,FILE *p围绕文件描述符操作,非负整数默认打开三个流:stdin/stdout/stderr默认打开三个文件描述符:0/1/2只能操作普通文件可以操作除了目录以外的任意类型文件可移植性更强可移植性弱函数打开文件: fopen \freopen打开文件: open关闭文件 :fclose关闭文件:close。

weixin_67273669的博客 952
上一篇: 基于TCP+sqlite3+线程等技术实现的聊天室(Linux操作系统+C语言)
下一篇: 文件IO总结(基于Linux系统)
SELSL
博客等级 码龄3年 225粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值