day2: 作业

This commit is contained in:
flykhan 2023-08-15 23:23:31 +08:00
parent ef704ce9f1
commit a7794612ae
12 changed files with 348 additions and 0 deletions

2
day2/homework/a.txt Normal file
View File

@ -0,0 +1,2 @@
hhhnihao

3
day2/homework/b.txt Normal file
View File

@ -0,0 +1,3 @@
nihao
helloworld
hi ff

33
day2/homework/h1.c Normal file
View File

@ -0,0 +1,33 @@
// 编写一个程序使用open系统调用创建一个新文件并使用write系统调用将字符串写入该文件。
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h> // perror
int main(int argc, char const *argv[])
{
// 打开文件 "a.txt",如果文件不存在则创建,以只写方式打开,如果文件已存在则打开失败,打开后将文件内容截断为空
int fd = open("a.txt", O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0644);
if (fd < 0)
{
perror("open"); // 打印错误信息
return -1;
}
char content_line[] = "hello\nworld\n";
ssize_t len = write(fd, content_line, sizeof(content_line)); // 向文件写入 content_line 的内容
if (len < 0)
{
perror("write"); // 打印错误信息
return -1;
}
if (close(fd) < 0) // 关闭文件描述符
{
perror("close"); // 打印错误信息
return -1;
}
return 0;
}

33
day2/homework/h2.c Normal file
View File

@ -0,0 +1,33 @@
// 编写一个程序使用open系统调用打开一个已存在的文件并使用read系统调用从文件中读取内容并将读取到的内容打印到控制台上。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
// 打开文件
int fd = open("a.txt", O_RDONLY);
if (fd < 0)
{
perror("open"); // 打开文件失败时打印错误信息
return -1;
}
char buf[1024] = "";
ssize_t len = read(fd, buf, sizeof(buf)); // 从文件中读取内容
if (len != -1)
{
// printf("%s\n", buf); // 将读取到的内容打印到控制台上
write(STDOUT_FILENO, buf, len); // 将读取到的内容写入标准输出
}
if (close(fd) < 0)
{
perror("close"); // 关闭文件失败时打印错误信息
return -1;
}
return 0;
}

23
day2/homework/h3.c Normal file
View File

@ -0,0 +1,23 @@
// 编写一个程序创建一个子进程并在子进程中打印出自己的进程IDPID在父进程中打印出子进程的PID。
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
pid_t pid = fork();
if (pid < 0)
{
printf("fork error\n");
return -1;
}
if (pid == 0)
{
printf("子进程打印子进程ID: %d\n", getpid());
}
else
{
printf("父进程打印子进程ID: %d\n", pid);
}
return 0;
}

48
day2/homework/h4.c Normal file
View File

@ -0,0 +1,48 @@
/*
使open系统调用打开一个已存在的文件使lseek系统调用将文件指针移动到文件末尾使write系统调用将用户从控制台输入的内容追加到文件末尾
man 2 lseek
off_t lseek(int fd, off_t offset, int whence);
whence SEEK_SET SEEK_CUR SEEK_END
*/
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
int main(int argc, char const *argv[])
{
int fd = open("a.txt", O_RDWR); // 以读写模式打开文件
if (fd < 0)
{
perror("open"); // 打开文件失败时打印错误信息
return -1;
}
if (argc != 2)
{
perror("usage: ./a something"); // 如果命令行参数不正确,打印使用说明
return -1;
}
const char *input_buf = argv[1]; // 获取用户输入的内容
off_t file_end = lseek(fd, 0, SEEK_END); // 将文件指针移动到文件末尾
char buf[1024] = "";
sprintf(buf, "%s", input_buf); // 将用户输入的内容存储在缓冲区中
int wrt = write(fd, buf, strlen(buf)); // 使用strlen获取写入的字节数
if (wrt < 0)
{
perror("write"); // 写入文件失败时打印错误信息
return -1;
}
if (close(fd) < 0)
{
perror("close"); // 关闭文件失败时打印错误信息
return -1;
}
return 0;
}

32
day2/homework/h5.c Normal file
View File

@ -0,0 +1,32 @@
/*
使opendir系统调用打开一个已存在的目录使readdir系统调用遍历目录中的文件和子目录
*/
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
int main(int argc, char const *argv[])
{
DIR *dir = opendir("/home/flykhan/qfedu-linux-advanced-level");
if (NULL == dir)
{
perror("opendir"); // 打开目录失败时输出错误信息
return -1;
}
struct dirent *dirent;
while ((dirent = readdir(dir)) != NULL)
{
if (strcmp(dirent->d_name, ".") != 0 && strcmp(dirent->d_name, "..") != 0)
{
if (dirent->d_type == DT_DIR || dirent->d_type == DT_REG)
{
printf("%s\n", dirent->d_name); // 打印目录中的文件和子目录名
}
}
}
closedir(dir); // 关闭目录
return 0;
}

51
day2/homework/h6.c Normal file
View File

@ -0,0 +1,51 @@
// 编写一个程序使用open系统调用创建一个新文件并使用write系统调用将用户从控制台输入的内容写入该文件直到用户输入 "quit"为止。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
int fd = open("b.txt", O_RDWR | O_CREAT | O_TRUNC, 0600);
if (fd < 0)
{
perror("open");
return -1;
}
char buf[1024] = ""; // 初始化缓冲区
ssize_t input_len;
while (strcmp(buf, "quit\n") != 0) // 检查用户输入是否为"quit\n"
{
memset(buf, 0, sizeof(buf)); // 清空缓冲区
input_len = read(STDIN_FILENO, buf, sizeof(buf));
if (input_len < 0)
{
perror("read");
return -1;
}
if (strcmp(buf, "quit\n") != 0) // 检查用户输入是否为"quit\n"
{
int wrt = write(fd, buf, input_len);
if (wrt < 0)
{
perror("write");
return -1;
}
}
}
if (close(fd) < 0)
{
perror("close");
return -1;
}
return 0;
}

37
day2/homework/h7.c Normal file
View File

@ -0,0 +1,37 @@
/*
wait或waitpid
*/
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char const *argv[])
{
pid_t pid = fork(); // 创建子进程
if (pid < 0)
{
perror("fork");
return -1;
}
if (pid == 0) // 子进程
{
int i;
scanf("%d", &i); // 从键盘读取一个整数
return i; // 子进程返回读取到的整数
}
else // 父进程
{
int status;
waitpid(pid, &status, 0); // 等待子进程结束,并获取返回状态
if (WIFEXITED(status)) // 检查子进程是否正常退出
{
int child_i = WEXITSTATUS(status); // 获取子进程的返回值
printf("子进程读取到的数字为: %d\n", child_i);
}
}
return 0;
}

49
day2/homework/h8.c Normal file
View File

@ -0,0 +1,49 @@
// 请分析如下程序如何实现创建2个子进程 第一个子进程输出ABC, 第二子进程输出 DEF。
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
// 创建2个子进程
int i;
for (i = 0; i < 2; i++)
{
pid_t pid = fork();
if (pid < 0)
{
perror("fork");
return -1;
}
else if (pid == 0)
{
// 子进程的代码
if (i == 0)
{
// 第一个子进程输出"ABC"
printf("ABC\n");
}
else if (i == 1)
{
// 第二个子进程输出"DEF"
printf("DEF\n");
}
return 0;
}
}
// 等待所有子进程结束
while (1)
{
// 等待任意子进程结束并获取已终止子进程的进程ID
pid_t terminated_pid = wait(NULL);
if (terminated_pid < 0)
{
// 所有子进程都已经结束
break;
}
}
return 0;
}

14
day2/homework/hx.c Normal file
View File

@ -0,0 +1,14 @@
#include <stdio.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
int flags = fcntl(STDIN_FILENO, F_GETFL);
flags ^= O_NONBLOCK;
fcntl(STDIN_FILENO, F_SETFL, flags);
return 0;
}

23
day2/homework/readme.md Normal file
View File

@ -0,0 +1,23 @@
1. 第一题代码中使用了以下头文件:
- `<sys/types.h>`:定义了一些基本的系统数据类型,如 `pid_t`、`ssize_t` 等。
- `<sys/stat.h>`:定义了文件状态的结构体 `struct stat`,以及一些用于检查文件状态的函数。
- `<unistd.h>`:提供了对 POSIX 系统调用的访问,包括文件操作、进程控制、系统调用等。
- `<fcntl.h>`:定义了文件控制操作的常量,如打开文件的标志位 `O_WRONLY`、`O_CREAT`、`O_EXCL`、`O_TRUNC` 等。
- `<stdio.h>`:提供了标准输入输出函数,如 `perror()` 用于打印错误信息。
这些头文件的作用如下:
- `<sys/types.h>``<sys/stat.h>` 提供了文件状态和类型相关的定义,例如 `open()` 函数中的文件权限参数 `0644` 就是在 `<sys/stat.h>` 中定义的。
- `<unistd.h>` 中的 `open()` 函数用于打开文件,`write()` 函数用于向文件写入数据,`close()` 函数用于关闭文件描述符。
- `<fcntl.h>` 中的常量用于指定文件打开的方式和属性,例如 `O_WRONLY` 表示以只写方式打开文件,`O_CREAT` 表示如果文件不存在则创建文件,`O_EXCL` 表示与 `O_CREAT` 一起使用时,如果文件已经存在则打开失败,`O_TRUNC` 表示如果文件存在则截断文件。
- `<stdio.h>` 中的 `perror()` 函数用于将上一个函数发生的错误信息输出到标准错误流,并附加一个自定义的错误描述。
这些头文件提供了在代码中进行文件操作和错误处理所需的函数和定义。通过包含这些头文件,我们可以使用相应的函数和常量来操作文件和处理错误。