标准输入输出

程序与用户的交互

输入输出是程序与用户交互的重要方式。东巴文(db-w.cn) 将带你深入理解C语言的标准输入输出,掌握程序与用户交互的核心技能。

💡 东巴文观点:输入输出是程序的窗口,通过它程序可以接收用户的指令,向用户展示结果。

标准输入输出概述

标准流

东巴文标准流表

标准流 文件指针 设备 东巴文说明
标准输入 stdin 键盘 程序的输入源
标准输出 stdout 屏幕 程序的输出目标
标准错误 stderr 屏幕 错误信息输出

东巴文说明

  • 标准流在程序启动时自动打开
  • 标准流在程序结束时自动关闭
  • 可以重定向到文件或其他设备

printf函数

基本用法

东巴文语法

int printf(const char *format, ...);

东巴文说明

  • format:格式字符串
  • ...:可变参数列表
  • 返回值:输出的字符数

格式说明符

东巴文格式说明符表

格式符 类型 示例 输出 东巴文说明
%d int printf("%d", 42); 42 十进制整数
%i int printf("%i", 42); 42 十进制整数
%u unsigned int printf("%u", 42); 42 无符号整数
%o int printf("%o", 42); 52 八进制整数
%x int printf("%x", 255); ff 十六进制(小写)
%X int printf("%X", 255); FF 十六进制(大写)
%f float/double printf("%f", 3.14); 3.140000 浮点数
%e float/double printf("%e", 3.14); 3.140000e+00 科学计数法(小写)
%E float/double printf("%E", 3.14); 3.140000E+00 科学计数法(大写)
%g float/double printf("%g", 3.14); 3.14 自动选择%f或%e
%c char printf("%c", 'A'); A 字符
%s char* printf("%s", "东巴文"); 东巴文 字符串
%p void* printf("%p", ptr); 0x7fff... 指针地址
%% - printf("%%"); % 百分号

宽度和精度

东巴文宽度和精度表

格式 示例 输出 东巴文说明
%5d printf("%5d", 42); 42 最小宽度5,右对齐
%-5d printf("%-5d", 42); 42 最小宽度5,左对齐
%05d printf("%05d", 42); 00042 最小宽度5,用0填充
%.2f printf("%.2f", 3.14159); 3.14 精度2位小数
%6.2f printf("%6.2f", 3.14159); 3.14 宽度6,精度2
%.5s printf("%.5s", "东巴文教程"); 东巴文教程 截取前5个字符

示例代码

#include <stdio.h>

int main() {
    printf("=== 东巴文printf示例 ===\n\n");
    
    // 整数
    int num = 42;
    printf("十进制:%d\n", num);
    printf("八进制:%o\n", num);
    printf("十六进制:%x\n", num);
    printf("十六进制:%X\n", num);
    
    // 浮点数
    float f = 3.14159f;
    printf("\n默认:%f\n", f);
    printf("精度2:%.2f\n", f);
    printf("精度5:%.5f\n", f);
    printf("科学计数法:%e\n", f);
    
    // 字符和字符串
    char ch = 'A';
    char str[] = "东巴文";
    printf("\n字符:%c\n", ch);
    printf("字符串:%s\n", str);
    
    // 宽度和对齐
    printf("\n右对齐:|%10d|\n", 42);
    printf("左对齐:|%-10d|\n", 42);
    printf("补零:|%010d|\n", 42);
    
    return 0;
}

转义字符

东巴文转义字符表

转义字符 含义 ASCII码 东巴文说明
\n 换行 10 移到下一行开头
\r 回车 13 移到当前行开头
\t 水平制表 9 跳到下一个制表位
\v 垂直制表 11 垂直跳格
\b 退格 8 删除前一个字符
\f 换页 12 换页
\a 响铃 7 系统响铃
\\ 反斜杠 92 输出反斜杠
\' 单引号 39 输出单引号
\" 双引号 34 输出双引号
\? 问号 63 输出问号
\0 空字符 0 字符串结束标志

示例代码

#include <stdio.h>

int main() {
    printf("=== 东巴文转义字符示例 ===\n\n");
    
    printf("换行:第一行\n第二行\n");
    printf("制表:列1\t列2\t列3\n");
    printf("退格:ABC\bD\n");  // ABD
    printf("回车:123\r456\n");  // 456
    printf("响铃:\a\n");
    printf("引号:\"东巴文\"\n");
    printf("反斜杠:C:\\Program Files\\\n");
    
    return 0;
}

scanf函数

基本用法

东巴文语法

int scanf(const char *format, ...);

东巴文说明

  • format:格式字符串
  • ...:变量地址列表
  • 返回值:成功读取的项目数

格式说明符

东巴文scanf格式符表

格式符 类型 示例 东巴文说明
%d int* scanf("%d", &num); 读取整数
%i int* scanf("%i", &num); 读取整数(自动识别进制)
%u unsigned int* scanf("%u", &num); 读取无符号整数
%o int* scanf("%o", &num); 读取八进制整数
%x int* scanf("%x", &num); 读取十六进制整数
%f float* scanf("%f", &f); 读取浮点数
%lf double* scanf("%lf", &d); 读取双精度浮点数
%c char* scanf("%c", &ch); 读取字符
%s char* scanf("%s", str); 读取字符串(遇空格停止)

示例代码

#include <stdio.h>

int main() {
    int age;
    float score;
    char name[50];
    
    printf("=== 东巴文scanf示例 ===\n\n");
    
    printf("请输入年龄:");
    scanf("%d", &age);
    
    printf("请输入成绩:");
    scanf("%f", &score);
    
    printf("请输入姓名:");
    scanf("%s", name);  // 注意:遇空格停止
    
    printf("\n=== 输出结果 ===\n");
    printf("姓名:%s\n", name);
    printf("年龄:%d\n", age);
    printf("成绩:%.2f\n", score);
    
    return 0;
}

注意事项

#include <stdio.h>

int main() {
    int a, b;
    char ch;
    
    // ⚠️ 注意:必须使用地址
    // scanf("%d", a);  // 错误:缺少&
    scanf("%d", &a);    // 正确
    
    // ⚠️ 注意:scanf读取字符串时遇空格停止
    char str[100];
    printf("请输入字符串:");
    scanf("%s", str);  // 输入"东巴文 教程",只读取"东巴文"
    printf("读取的字符串:%s\n", str);
    
    // ⚠️ 注意:%c会读取所有字符,包括空格和换行
    printf("请输入一个字符:");
    scanf(" %c", &ch);  // 前面的空格用于跳过空白字符
    
    printf("读取的字符:%c\n", ch);
    
    return 0;
}

东巴文提示

  • scanf 必须使用变量的地址(&
  • %s 读取字符串时遇空格停止
  • %c 前加空格可以跳过空白字符

返回值检查

#include <stdio.h>

int main() {
    int a, b;
    
    printf("请输入两个整数:");
    int result = scanf("%d %d", &a, &b);
    
    if (result == 2) {
        printf("读取成功:a = %d, b = %d\n", a, b);
    } else if (result == 1) {
        printf("只读取了一个整数:%d\n", a);
    } else {
        printf("读取失败\n");
    }
    
    return 0;
}

字符输入输出函数

getchar和putchar

#include <stdio.h>

int main() {
    char ch;
    
    printf("请输入一个字符:");
    ch = getchar();  // 读取一个字符
    
    printf("你输入的字符是:");
    putchar(ch);     // 输出一个字符
    putchar('\n');
    
    return 0;
}

gets和puts

#include <stdio.h>

int main() {
    char str[100];
    
    printf("请输入一行文字:");
    gets(str);  // 读取一行(不安全,已废弃)
    
    printf("你输入的是:");
    puts(str);  // 输出字符串并换行
    
    return 0;
}

东巴文警告gets 函数不安全,可能导致缓冲区溢出,应使用 fgets 替代。

fgets

#include <stdio.h>

int main() {
    char str[100];
    
    printf("请输入一行文字:");
    fgets(str, sizeof(str), stdin);  // 安全的读取方式
    
    printf("你输入的是:");
    puts(str);
    
    return 0;
}

东巴文说明fgets 可以指定最大读取长度,避免缓冲区溢出。

格式化字符串函数

sprintf

#include <stdio.h>

int main() {
    char buffer[100];
    int age = 25;
    float score = 85.5f;
    
    // 将格式化字符串写入buffer
    sprintf(buffer, "年龄:%d, 成绩:%.1f", age, score);
    
    printf("%s\n", buffer);
    
    return 0;
}

snprintf

#include <stdio.h>

int main() {
    char buffer[10];
    int num = 123456;
    
    // 安全的格式化字符串(指定最大长度)
    snprintf(buffer, sizeof(buffer), "%d", num);
    
    printf("%s\n", buffer);  // 123456
    
    return 0;
}

东巴文提示snprintfsprintf 更安全,可以指定缓冲区大小。

sscanf

#include <stdio.h>

int main() {
    char str[] = "25 85.5";
    int age;
    float score;
    
    // 从字符串中读取数据
    sscanf(str, "%d %f", &age, &score);
    
    printf("年龄:%d\n", age);
    printf("成绩:%.1f\n", score);
    
    return 0;
}

格式化输入输出进阶

字段宽度

#include <stdio.h>

int main() {
    int a = 42;
    
    printf("=== 东巴文字段宽度示例 ===\n\n");
    
    // 最小宽度
    printf("|%d|\n", a);      // |42|
    printf("|%5d|\n", a);     // |   42|
    printf("|%-5d|\n", a);    // |42   |
    
    // 补零
    printf("|%05d|\n", a);    // |00042|
    
    // 浮点数
    float f = 3.14159f;
    printf("|%f|\n", f);      // |3.141590|
    printf("|%.2f|\n", f);    // |3.14|
    printf("|%8.2f|\n", f);   // |    3.14|
    printf("|%-8.2f|\n", f);  // |3.14    |
    
    return 0;
}

动态宽度

#include <stdio.h>

int main() {
    int num = 42;
    int width = 10;
    
    // 动态指定宽度
    printf("|%*d|\n", width, num);  // |        42|
    
    // 动态指定精度
    float f = 3.14159f;
    int precision = 3;
    printf("|%.*f|\n", precision, f);  // |3.142|
    
    // 动态指定宽度和精度
    printf("|%*.*f|\n", 10, 3, f);  // |     3.142|
    
    return 0;
}

错误处理

检查返回值

#include <stdio.h>

int main() {
    int num;
    
    printf("请输入一个整数:");
    
    if (scanf("%d", &num) == 1) {
        printf("读取成功:%d\n", num);
    } else {
        printf("输入错误!\n");
        
        // 清空输入缓冲区
        while (getchar() != '\n');
    }
    
    return 0;
}

清空输入缓冲区

#include <stdio.h>

int main() {
    int a;
    char ch;
    
    printf("请输入一个整数:");
    scanf("%d", &a);
    
    // 清空输入缓冲区
    while (getchar() != '\n');
    
    printf("请输入一个字符:");
    scanf("%c", &ch);
    
    printf("整数:%d, 字符:%c\n", a, ch);
    
    return 0;
}

东巴文提示scanf 读取整数后会留下换行符,需要清空缓冲区才能正确读取后续字符。

东巴文最佳实践

1. 使用安全的函数

// ❌ 不推荐:使用不安全的函数
char str[10];
gets(str);  // 可能导致缓冲区溢出

// ✅ 推荐:使用安全的函数
fgets(str, sizeof(str), stdin);

2. 检查返回值

#include <stdio.h>

int main() {
    int num;
    
    printf("请输入一个整数:");
    
    if (scanf("%d", &num) != 1) {
        printf("输入错误!\n");
        return 1;
    }
    
    printf("你输入的整数是:%d\n", num);
    
    return 0;
}

3. 格式化输出

#include <stdio.h>

int main() {
    printf("=== 东巴文成绩单 ===\n\n");
    printf("%-10s %5s %5s\n", "姓名", "成绩", "等级");
    printf("%-10s %5d %5c\n", "张三", 85, 'B');
    printf("%-10s %5d %5c\n", "李四", 92, 'A');
    printf("%-10s %5d %5c\n", "王五", 78, 'C');
    
    return 0;
}

4. 用户友好的提示

#include <stdio.h>

int main() {
    int age;
    
    // ✅ 提供清晰的提示
    printf("请输入您的年龄(1-120):");
    
    if (scanf("%d", &age) != 1) {
        printf("错误:请输入有效的数字!\n");
        return 1;
    }
    
    if (age < 1 || age > 120) {
        printf("错误:年龄必须在1-120之间!\n");
        return 1;
    }
    
    printf("您的年龄是:%d岁\n", age);
    
    return 0;
}

东巴文验证清单

完成本章学习后,请确认:

  • 理解标准输入输出的概念
  • 掌握printf函数的使用
  • 掌握scanf函数的使用
  • 掌握格式说明符的使用
  • 掌握宽度和精度的设置
  • 掌握转义字符的使用
  • 掌握字符输入输出函数
  • 掌握格式化字符串函数
  • 了解输入输出的错误处理
  • 能编写用户友好的交互程序

下一步学习

掌握标准输入输出后,你可以继续学习:

如果遇到问题,欢迎访问 东巴文(db-w.cn) 获取帮助!


东巴文(db-w.cn) - 让编程学习更简单

📦 东巴文输入输出提示:输入输出是程序与用户交互的桥梁,掌握输入输出函数是编写交互式程序的关键。在 db-w.cn,我们会通过大量实例帮你掌握输入输出的使用!