您的位置:首页 > 文旅 > 旅游 > 开发公司发生的物业费用所得税申报_烟台网站建设托管_衡水seo培训_网站如何优化排名

开发公司发生的物业费用所得税申报_烟台网站建设托管_衡水seo培训_网站如何优化排名

2024/12/22 19:05:19 来源:https://blog.csdn.net/2302_80378107/article/details/144577952  浏览:    关键词:开发公司发生的物业费用所得税申报_烟台网站建设托管_衡水seo培训_网站如何优化排名
开发公司发生的物业费用所得税申报_烟台网站建设托管_衡水seo培训_网站如何优化排名

1.Shell自定义

1.初始化

定义全局变量environ,把g_env的内容用memset初始化为0,这里用malloc开辟的空间为对应环境变量的长度+1,多1位置是最后结束符0,strcpy把此时的对应的环境变量拷贝到g_env里面,下面是新增一个环境变量,要把最后一位置成NULL,最后循环把环境变量再导入进去,在循环体内,putenv 函数被用来将 g_env 数组中的每个字符串设置为环境变量。putenv 函数接受一个格式为 KEY=VALUE 的字符串,并将其添加到进程的环境变量中。如果 KEY 已经存在,则其值会被更新为 VALUE,最后把environ指向g_env。

void InitEnv()
{extern char **environ;memset(g_env, 0, sizeof(g_env));g_envs = 0;//本来要从配置文件来//1. 获取环境变量for(int i = 0; environ[i]; i++){// 1.1 申请空间g_env[i] = (char*)malloc(strlen(environ[i])+1);strcpy(g_env[i], environ[i]);g_envs++;}g_env[g_envs++] = (char*)"HAHA=for_test"; //for_testg_env[g_envs] = NULL;//2. 导成环境变量for(int i = 0; g_env[i]; i++){putenv(g_env[i]);}environ = g_env;
}

2.检测内建命令

读取g_argv的第一个字符判断是否为内建命令。

bool CheckAndExecBuiltin()
{std::string cmd = g_argv[0];if(cmd == "cd"){Cd();return true;}else if(cmd == "echo"){Echo();return true;}else if(cmd == "export"){}else if(cmd == "alias"){// std::string nickname = g_argv[1];// alias_list.insert(k, v);}return false;
}

3.内建命令实现

1.Cd

 内建命令要在父进程实现,用chdir函数改变当前路径,要判断是否有命令行参数,用g_argv的第二个字符得知要到哪一个路径。

2.Echo

这里需要命令行参数达到2,然后用opt指向第二个字符,如果opt(这里为指针)的内容与$?就要看退出码的值,lastcode的值在子进程结束用WEXITSTATUS得到了,如果opt的第二个字符(char)等于'$'(""是一个字符串const char*类型),表示要打印环境变量的值opt.substr(1)构造从opt索引1到尾的子串(但是这里argc为2所以这个子串只有一个字符就是环境变量名字),env_value获取getenv得到的字符串值。

bool Cd()
{// cd argc = 1if(g_argc == 1){std::string home = GetHome();if(home.empty()) return true;chdir(home.c_str());}else{std::string where = g_argv[1];// cd - / cd ~if(where == "-"){// Todu}else if(where == "~"){// Todu}else{chdir(where.c_str());}}return true;
}void Echo()
{if(g_argc == 2){// echo "hello world"// echo $?// echo $PATHstd::string opt = g_argv[1];if(opt == "$?"){std::cout << lastcode << std::endl;lastcode = 0;}else if(opt[0] == '$'){std::string env_name = opt.substr(1);const char *env_value = getenv(env_name.c_str());if(env_value)std::cout << env_value << std::endl;}else{std::cout << opt << std::endl;}}
}

3.更新pwd

在cd后查看环境变量的pwd,不写更新的话是不变的,getcwd获取当前路径,如果不为空就写入到cwdenv里面,然后把"PWD=%s"和cwd(路径名)添加到环境变量里面,因为以及存在所以会更新值,完成更新路径。

const char *GetPwd()
{//const char *pwd = getenv("PWD");const char *pwd = getcwd(cwd, sizeof(cwd));if(pwd != NULL){snprintf(cwdenv, sizeof(cwdenv), "PWD=%s", cwd);putenv(cwdenv);}return pwd == NULL ? "None" : pwd;
}

补充:

`chdir` 函数是用于改变当前工作目录的函数,其原型定义在 `<unistd.h>` 头文件中。以下是 `chdir` 函数的详细参数解释:

### 函数原型
```c
int chdir(const char *path);
```

### 参数
- `path`:这是一个指向字符的指针,表示要切换到的目标目录的路径。这个路径可以是绝对路径,也可以是相对路径。指定的目录必须存在,否则函数调用会失败。

### 返回值
- 成功:返回 `0`。
- 失败:返回 `-1`,并设置 `errno` 以指示错误原因。

### 错误处理
当 `chdir` 函数失败时,可以通过检查 `errno` 来确定错误原因。常见的错误包括但不限于:
- `ENOENT`:路径不存在。
- `ENOTDIR`:路径中的某个组件不是目录。
- `EACCES`:没有权限访问目标目录。

### 示例代码
```c
#include <unistd.h>
#include <stdio.h>

int main() {
    const char *path = "/path/to/directory";
    if (chdir(path) == 0) {
        printf("成功切换到目录: %s\n", path);
    } else {
        perror("切换目录失败");
    }
    return 0;
}
```

在这个示例中,如果路径切换成功,将打印出成功信息;如果失败,将输出错误信息。
 

在 C++ 中,`substr` 是 `std::string` 类的一个成员函数,用于返回字符串的一个子串。这个函数可以有两种形式:

1. 接受一个参数的版本:
   - `substr(size_t pos = 0)`:返回从位置 `pos` 开始到字符串末尾的子串。如果 `pos` 大于字符串的长度,将返回一个空字符串。

2. 接受两个参数的版本:
   - `substr(size_t pos, size_t len)`:返回从位置 `pos` 开始、长度为 `len` 的子串。如果 `pos` 大于字符串的长度,同样返回一个空字符串。如果 `pos + len` 超出了字符串的长度,那么子串将只包含从 `pos` 到字符串末尾的部分。

在你提到的 `substr(1)` 中,`1` 是传递给 `substr` 函数的第一个版本的第一个参数,表示从字符串的第二个字符开始提取子串,直到字符串的末尾。在 C++ 中,字符串的索引是从 `0` 开始的,所以 `1` 表示第二个字符。

下面是一个使用 `substr(1)` 的简单示例:

```cpp
#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";
    std::string sub = str.substr(1); // 从索引1开始,提取到字符串末尾的子串
    std::cout << sub << std::endl; // 输出 "ello, World!"
    return 0;
}
```

在这个例子中,`substr(1)` 将返回 "ello, World!",因为它从字符串 "Hello, World!" 的第二个字符开始提取,直到字符串的末尾。
 

`getcwd` 函数的参数如下:

1. `buf`:这是一个指向字符数组的指针,用于存储当前工作目录的路径。

2. `size`:这是一个`size_t`类型的值,表示`buf`数组的大小,即可以存储的最大字符数。

使用`getcwd`函数时,第一个参数`buf`是用于接收当前工作目录路径的缓冲区,第二个参数`size`是这个缓冲区的大小。如果`buf`为`NULL`且`size`为0,`getcwd`会动态分配内存(需要手动释放)来存储路径。
 

总代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <cstring>
#include <unordered_map>#define COMMAND_SIZE 1024
#define FORMAT "[%s@%s %s]# "// 下面是shell定义的全局数据// 1. 命令行参数表
#define MAXARGC 128
char *g_argv[MAXARGC];
int g_argc = 0; // 2. 环境变量表
#define MAX_ENVS 100
char *g_env[MAX_ENVS];
int g_envs = 0;// 3. 别名映射表
std::unordered_map<std::string, std::string> alias_list;// for test
char cwd[1024];
char cwdenv[1024];// last exit code
int lastcode = 0;const char *GetUserName()
{const char *name = getenv("USER");return name == NULL ? "None" : name;
}const char *GetHostName()
{const char *hostname = getenv("HOSTNAME");return hostname == NULL ? "None" : hostname;
}const char *GetPwd()
{//const char *pwd = getenv("PWD");const char *pwd = getcwd(cwd, sizeof(cwd));if(pwd != NULL){snprintf(cwdenv, sizeof(cwdenv), "PWD=%s", cwd);putenv(cwdenv);}return pwd == NULL ? "None" : pwd;
}const char *GetHome()
{const char *home = getenv("HOME");return home == NULL ? "" : home;
}void InitEnv()
{extern char **environ;memset(g_env, 0, sizeof(g_env));g_envs = 0;//本来要从配置文件来//1. 获取环境变量for(int i = 0; environ[i]; i++){// 1.1 申请空间g_env[i] = (char*)malloc(strlen(environ[i])+1);strcpy(g_env[i], environ[i]);g_envs++;}g_env[g_envs++] = (char*)"HAHA=for_test"; //for_testg_env[g_envs] = NULL;//2. 导成环境变量for(int i = 0; g_env[i]; i++){putenv(g_env[i]);}environ = g_env;
}//command
bool Cd()
{// cd argc = 1if(g_argc == 1){std::string home = GetHome();if(home.empty()) return true;chdir(home.c_str());}else{std::string where = g_argv[1];// cd - / cd ~if(where == "-"){// Todu}else if(where == "~"){// Todu}else{chdir(where.c_str());}}return true;
}void Echo()
{if(g_argc == 2){// echo "hello world"// echo $?// echo $PATHstd::string opt = g_argv[1];if(opt == "$?"){std::cout << lastcode << std::endl;lastcode = 0;}else if(opt[0] == '$'){std::string env_name = opt.substr(1);const char *env_value = getenv(env_name.c_str());if(env_value)std::cout << env_value << std::endl;}else{std::cout << opt << std::endl;}}
}// / /a/b/c
std::string DirName(const char *pwd)
{
#define SLASH "/"std::string dir = pwd;if(dir == SLASH) return SLASH;auto pos = dir.rfind(SLASH);if(pos == std::string::npos) return "BUG?";return dir.substr(pos+1);
}void MakeCommandLine(char cmd_prompt[], int size)
{snprintf(cmd_prompt, size, FORMAT, GetUserName(), GetHostName(), DirName(GetPwd()).c_str());//snprintf(cmd_prompt, size, FORMAT, GetUserName(), GetHostName(), GetPwd());
}void PrintCommandPrompt()
{char prompt[COMMAND_SIZE];MakeCommandLine(prompt, sizeof(prompt));printf("%s", prompt);fflush(stdout);
}bool GetCommandLine(char *out, int size)
{// ls -a -l => "ls -a -l\n" 字符串char *c = fgets(out, size, stdin);if(c == NULL) return false;out[strlen(out)-1] = 0; // 清理\nif(strlen(out) == 0) return false;return true;
}// 3. 命令行分析 "ls -a -l" -> "ls" "-a" "-l"
bool CommandParse(char *commandline)
{
#define SEP " "g_argc = 0;// 命令行分析 "ls -a -l" -> "ls" "-a" "-l"g_argv[g_argc++] = strtok(commandline, SEP);while((bool)(g_argv[g_argc++] = strtok(nullptr, SEP)));g_argc--;return g_argc > 0 ? true:false;
}void PrintArgv()
{for(int i = 0; g_argv[i]; i++){printf("argv[%d]->%s\n", i, g_argv[i]);}printf("argc: %d\n", g_argc);
}bool CheckAndExecBuiltin()
{std::string cmd = g_argv[0];if(cmd == "cd"){Cd();return true;}else if(cmd == "echo"){Echo();return true;}else if(cmd == "export"){}else if(cmd == "alias"){// std::string nickname = g_argv[1];// alias_list.insert(k, v);}return false;
}int Execute()
{pid_t id = fork();if(id == 0){//childexecvp(g_argv[0], g_argv);exit(1);}int status = 0;// fatherpid_t rid = waitpid(id, &status, 0);if(rid > 0){lastcode = WEXITSTATUS(status);}return 0;
}int main()
{// shell 启动的时候,从系统中获取环境变量// 我们的环境变量信息应该从父shell统一来InitEnv();while(true){// 1. 输出命令行提示符PrintCommandPrompt();// 2. 获取用户输入的命令char commandline[COMMAND_SIZE];if(!GetCommandLine(commandline, sizeof(commandline)))continue;// 3. 命令行分析 "ls -a -l" -> "ls" "-a" "-l"if(!CommandParse(commandline))continue;//PrintArgv();// 检测别名// 4. 检测并处理内键命令if(CheckAndExecBuiltin())continue;// 5. 执行命令Execute();}//cleanup();return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com