配套代码笔记Github地址

目录

第三章 输入输出专题

input & output -> I/O(标准IO,文件IO)

内容

  1. 格式化输入输出函数:scanf, printf
  2. 字符输入输出函数:getchar, putchar
  3. 字符串输入输出函数:gets(!),puts

格式化输入输出函数

标准输出格式字符

标准输出修饰符

printf

int printf(const char *format, ...);
format: "%【修饰符】格式字符",参照图片标准输出修饰符和格式字符
  • 有关l修饰符的提醒
int main()
{
    FILE *fp;
    long a = 11;

    fp = fopen();

    // 可行,a定义了long型,与函数要求一致
    func(fp, a);

    // 早期的编译器不认可,这个12没有单位,不同编译器默认类型不同
    // 需要加上L修饰符
    func(fp, 12);
    func(fp, 12L);
    // 对于func(FILE *fp, long long i)
    func(fp, 12LL);
}

传输一个5G的文件

5LL*1204LL*1204LL*1204LL

定义一个宏,表示一年有多少秒

// 定义一年有多少秒
#define SEC_YEAR (60LL * 60LL * 24LL * 365LL)
  • 函数 变参与定参重载的区别

    • 变参:编译器只报警告,函数自己都不知道自己有多少个参数
    • 定参重载:编译报错
  • \n的作用

强制刷新缓冲区,以死循环调试举例。

// 不加\n,before while()存入了缓冲区,故不输出
// printf("[%s:%d]before while().", __FUNCTION__, __LINE__);
printf("[%s:%d]before while().\n", __FUNCTION__, __LINE__);
while (1)
{
}
// printf("[%s:%d]after while().", __FUNCTION__, __LINE__);
printf("[%s:%d]after while().\n", __FUNCTION__, __LINE__);
  • 完整代码
#include <stdio.h>
#include <stdlib.h>

/***
 * printf("%[修饰符]格式字符", 输出表项);
 *
 */

#define STRSIZE 10

int main()
{
    // printf("hello world\n");

    // char ch = 65;
    // printf("%c\n", ch);
    // out: A

    int i = 255;
    float f = 123.45678;
    char str[STRSIZE] = "helloworld";
    double dou = 123.456;
    long long l = 123456;
    // 不加\n,before while()存入了缓冲区,故不输出
    // printf("[%s:%d]before while().", __FUNCTION__, __LINE__);
    printf("[%s:%d]before while().\n", __FUNCTION__, __LINE__);
    while (1)
    {
    }
    // printf("[%s:%d]after while().", __FUNCTION__, __LINE__);
    printf("[%s:%d]after while().\n", __FUNCTION__, __LINE__);
    // printf("f = %8.1f\n", f);
    // out:f =    123.5
    // printf("i = %2d\n", i);
    // out: i = 123

    // printf("%-10.5s[over]\n", str);
    // printf("%+10.5s[over]\n", str);
    // out:
    // hello     [over]
    //      hello[over]

    // 同样对于i进行八进制核对十六进制的输出
    //  printf("i = %#o\n", i);
    //  out: i = 0377
    //  printf("i = %#x\n", i);
    //  out: i = 0xff

    // printf("dou = %lf\n", dou);
    // printf("l = %ld\n", l);
    // out:
    // dou = 123.456000
    // l = 123456

    // printf("hello world!\n");
    // 实参过多或者过少都会警告
    // printf("#d #e\n", i);
    // printf("#d #e\n", i, f, l);

    exit(0);
}

#if 0
func(FILE *fp, long i)
{
}

int main()
{
    FILE *fp;
    long a = 11;

    fp = fopen();

    // 可行,a定义了long型,与函数要求一致
    func(fp, a);

    // 早期的编译器不认可,这个12没有单位,不同编译器默认类型不同
    // 需要加上L修饰符
    func(fp, 12);
    func(fp, 12L);
    // 对于func(FILE *fp, long long i)
    func(fp, 12LL);
}
#endif

// 定义一年有多少秒
#define SEC_YEAR (60LL * 60LL * 24LL * 365LL)

scanf

int scanf(const char *format, 地址表);
format:抑制符*
%s非常危险,因为不知道储存空间的大小
放在循环结构中时要注意能否接收到正常内容
  • 完整代码
#include <stdio.h>
#include <stdlib.h>

/**
 *  int scanf(const char *format, 地址表);
 */

// #define STRSIZE 32
#define STRSIZE 3
// 除掉尾0占一个
// 相当于只能两个字符
// 但是这时候运行输入hello,不会报错
// 实际上是越界了

int main()
{
    int i;
    float f;
    char str[STRSIZE];
    int ret;
    char ch;

    printf("Please enter:\n");

    // scanf("%d", &i);
    // ch = getchar();

    // printf("i = %d, ch = %c\n", i, ch);
    /*
    out:
    Please enter:
    4 h
    i = 4, ch =
    ch被吞掉了
    */

    // scanf("%d", &i);
    // scanf("%*c%c", &ch);
    // 用 '%*c' 吃掉回车
    /*
    out:
    Please enter:
    5
    h
    i = 5, ch = h
    */

    printf("i = %d, ch = %c\n", i, ch);

#if 0
    // 输入a直接卡死,scanf直接放在循环中很危险
    // 需要加入校验,用ret接收scanf返回值
    while (1)
    {
        // scanf("%d", &i);

        ret = scanf("%d", &i);
        if (ret != 1)
        {
            printf("Enter Error!\n");
            break;
        }

        printf("i = %d\n", i);
    }
#endif

    // printf("Please enter fot str:\n");
    // 这种情况下,不能有任何间隔符
    // 输入hello world,只会得到hello
    // 对于scanf,不建议'%s'
    // scanf("%s", str);
    // printf("%s\n", str);

    // printf("Please enter for i[int]:\n");
    // 这里两个数字之间有',',输入就一定要有','
    // 最好不加,空格符可以是空格 回车 tab
    // scanf("%d,%f", &i, &f);
    // printf("i = %d\n", i);
    // printf("f = %f\n", f);

    exit(0);
}

字符输入输出函数

int getchar(void);// 返回int型是考虑出错的情况
int putchar(int c); 

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

int main()
{
    int ch;
    ch = getchar();
    putchar(ch);

    exit(0);
}

字符串输入输出函数

char *gets(char *s);
// 从标准输入读到内容放到s指针指向的缓冲区
// 停止条件:换行或者EOF
// 尾部会追加'\0'

int puts(const char *s);
// 将s指针缓冲区内容往外写
// 以换行符中止

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

#define STRSIZE 32

int main()
{
    char str[STRSIZE];
    gets(str);
    puts(str);

    exit(0);
}

gets非常危险,不会检查是否越界。使用的话用fgets来代替。

char *fgets(char *s, int size, FILE *stream);// 最多读到'size-1'个

getlineGNU libc的方言,可以动态内存保证读取一整行。

练习专题

夸脱水

一个水分子3.0e-23g,一夸脱水约950g。

变成,输入水的夸脱数,输出其包含的水分子质量。

static void water(void)
{
    float num;
    float sum;

    printf("Please input for num:");
    scanf("%f", &num);

    sum = num * KQ / WEIGHT;

    printf("Total = %e\n", sum);

    return;
}

三角形面积

输入三角形的三边长,求三角形面积。
static void area(void)
{
    float a, b, c;
    float s, area;

    printf("Please input:");
    scanf("%f%f%f", &a, &b, &c);
    // 对scanf做好校验是好习惯
    if (a + b <= c || b + c <= a || a + c <= b)
    {
        fprintf(stderr, "EINVAL!\n");
        exit(0);
    }

    printf("a = %f\n", a);
    printf("b = %f\n", b);
    printf("c = %f\n", c);

    // s = 1 / 2 * (a + b + c);
    s = 1.0 / 2 * (a + b + c);
    printf("s = %f\n", s);
    // s=0.000000
    // 1 / 2是int型计算,得到的是商0余1

    area = sqrt(s * (s - a) * (s - b) * (s - c));
    printf("area = %f\n", area);
}

编译需要-lmmakefile如下,千万要注意makefile要使用制表符缩进,而非空格。

CC=cc
CFLAGS=
LDFLAGS=-lm
TARGET=test
SRC=test.c
OBJ=$(SRC:.c=.o)

$(TARGET): $(OBJ)
    $(CC) -o $@ $^ $(LDFLAGS)

%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@

clean:
    rm -f $(TARGET) $(OBJ)

求根公式

ax^2^ + bx + c = 0,假设b^2^ - 4ac >0

x~1~ = (-b + sqrt( b*b - 4ac )) / 2a

x~2~ = (-b - sqrt( b*b - 4ac )) / 2a

void root(void)
{
    float a, b, c;
    float disc;
    float p, q;
    float x1, x2;

    printf("Please input :\n");
    scanf("%f%f%f", &a, &b, &c);

    if (b * b - 4 * a * c < 0)
    {
        fprintf(stderr, "EINVAL\n");
        exit(1);
    }
    disc = b * b - 4 * a * c;
    p = -b / 2 * a;
    q = sqrt(disc) / 2 * a;

    x1 = p + q;
    x2 = p - q;

    printf("x1 = %f\n", x1);
    printf("x2 = %f\n", x2);
}