C常见知识点复习


大纲:

  • bool类型
  • 文件结构(.h头文件,.c文件)
    • 头文件要有ifndef定义防止多次嵌套引入
  • 接收命令行参数
  • File I/O
    • 读文件(按行读)
    • 写文件
  • 内存分配
  • 结构体和定义类型 typedef

1. bool类型

需要引入头文件:stdbool.h

#include <stdbool.h>
int main()
{
bool arr[2] = { true, false };
return 0;
}

Refer:Use of bool in C - GeeksforGeeks

2. 文件结构

这里有一个模板。

文件名:book.h

#ifndef __BOOK__HEADER
#define __BOOK__HEADER
// 引入头文件
// 结构体定义
// 函数原型
#endif

文件名:book.c

#include "book.h"
// 引入头文件
// 函数实现

3. 命令行参数

很简单,main的两个参数 int argc 表示参数的个数(注意的是程序名字也占一个参数),char** argv接收的是具体的参数字符串。所以,程序名字:argv[0], 程序的实际第一个参数是:argv[1]。实际使用如下:

int main(int argc, char** argv) {
if (argc < 2) {
printf("Usage: %s text_file\n", argv[0]);
return 1;
}

char* filename = argv[1];
// TODO with the filename
return 0;
}

4. 文件读写 File IO

具体包括打开文件,关闭文件。读文件,写文件。
fopen/fclose; fgets/fscanf/fgetc/getline; fputs/fputc/fprintf

Refer: C - File I/O

// 打开文件
FILE* fp = fopen("test.txt", "r");
if (fp == NULL) {
puts("文件不存在!");
return 1;
}
// 关闭文件
fclose(fp);

4.1. 读文件

通过fgets读取到字符数组,缺点是:当一行很长时,只会读取一行的部分,而不是完整的行。

原型:char *fgets(char *str, int n, FILE *stream)

char buff[255];
char* line = fgets(buff, 255, fp);
while (line != NULL) {
printf("%s", res); // 注意:res包含换行符
line = fgets(buff, 255, fp);
}

通过 fscanf 格式化读入变量,优点,方便读取各种数据类型

char s[255];
int num;
fscanf(fp, "%d %s", &num, s);
printf("%d\n%s\n", num, s);

通过 getline 非标准的C函数来读取一行,可以完整读入一行

getline(&buffer,&size,stdin);
The latest and most trendy function for reading a string of text is getline(). It’s a new C library function, having appeared around 2010 or so.

   char* buf = (char*)malloc(sizeof(char)*6);
size_t size = 6, nRead;
nRead = getline(&buf, &size, fp);
printf("%s%zu chars read", buf, nRead); // buf的大小无所谓,太小会重新分配内存。buf读到的包含回车。nRead也包含回车
fclose(fp);

/* 输出:fp中第一行是: 15 abcde
15 abcde
9 chars read
*/

※ 注意要使用size_t类型定义getline的第二个参数,以及返回值。然后输出时,使用%zu表示无符号long类型。

The getline() Function | C For Dummies Blog

阅读:puts 和 printf 的细微区别
Refer:puts() vs printf() for printing a string - GeeksforGeeks

4.2. 写文件

跟读文件对应的。

通过fputs写字符串, 或者使用 fprintf 格式化输出。注意: 如果需要换行的话,需要手动添加\n。

原型: int fputs ( const char * str, FILE * stream );
原型: int fprintf ( FILE * stream, const char * format, … );

fputs("Hello 123\n", fp); // 换行
fprintf(fp, "%s %d\n", "nice try", 321);

Refer:fputs - C++ Reference
Refer:fprintf - C++ Reference

5. 内存分配

引入头文件: stdlib.h /* malloc, free, rand */
calloc相比malloc,它除了分配内存空间外,还会将内存空间的值清零。
realloc会调整内存大小,同时会复制内存中的值到新内存空间。

原型:void* malloc (size_t size);
原型:void free (void* ptr);
原型:void* calloc (size_t num, size_t size);
原型: void* realloc (void* ptr, size_t size);

使用malloc开辟空间时,一般用sizeof获取要存储的单元大小,同时对结果进行强类型转换。

typedef struct _Book {
// 全书的字符个数
int characterCount;
// 全书的行数
int lineCount;
// 书中的每一行内容
char **lines;
} Book;

/**
* input: An integer representing the maximum number of lines your book can hold.
* return: A pointer to an initialized Book.
*/
Book* make_book(int n) {
Book* book = (Book*) malloc(sizeof(Book));
book->characterCount = 0;
book->lineCount = 0;
book->lines = (char**)malloc(sizeof(char*) * n);
return book;
}

/**
* input: A pointer to a Book.
* return: None
*/
void burn_book(Book* book) {
for (int i = 0; i < book->lineCount; i++) {
free(book->lines[i]);
}
free(book->lines);
free(book);
}

6. 结构体和类型定义

typedef struct _Book {
// 全书的字符个数
int characterCount;
// 全书的行数
int lineCount;
// 书中的每一行内容
char **lines;
} Book;

文章作者: IT神助攻
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 IT神助攻 !
  目录