main函数执行前后的代码

本文详细解析了C++中atexit函数的作用、使用方法及其在程序退出时的执行顺序,包括如何在main函数结束后执行特定的清理工作,如内存释放等。
一、main结束 不代表整个进程结束
  (1)全局对象的构造函数会在main 函数之前执行,
          全局对象的析构函数会在main函数之后执行;
          用atexit注册的函数也会在main之后执行。
  (2)一些全局变量、对象和静态变量、对象的空间分配和赋初值就是在执行main函数之前,而main函数执行完后,还要去执行一些诸如释放空间、释放资源使用权等操作
  (3)进程启动后,要执行一些初始化代码(如设置环境变量等),然后跳转到main执行。全局对象的构造也在main之前。
二、main()之后执行的代码,用atexit注册的函数也会在main之后执行

  1. #include <iostream>  
  2. void fn1(void)  
  3. {  
  4.     printf("next.\n");   
  5. }  
  6.   
  7. void fn2(void)  
  8. {  
  9.     printf("executed ");   
  10. }  
  11.   
  12. void fn3(void)  
  13. {  
  14.     printf("is ");   
  15. }  
  16.   
  17. void fn4(void)  
  18. {  
  19.     printf("This ");  
  20. }   
  21.   
  22. int main(void)  
  23. {  
  24.     //   
  25.     // 注册需要在 main 函数结束后执行的函数.    
  26.     // 请注意它们的注册顺序和执行顺序  
  27.     // 在 main 函数结束后被调用,调用顺序与注册顺序相反。 先注册后执行。  
  28.     //  
  29.   
  30.     atexit(fn1);  
  31.     atexit(fn2);  
  32.     atexit(fn3);  
  33.     atexit(fn4);  
  34.   
  35.     // 这条输出语句具有参照性,它可不是最后一句输出.   
  36.     puts("This is executed first.");   
  37.   
  38.     // EXIT_SUCCESS 代表 0,它定义在 stdlib.h 中.   
  39.     // 我只是顺便提一下,也许你知道,但我担心你不知道,呵呵.   
  40.     //  
  41.     return EXIT_SUCCESS;  
  42. }  
关于atexit函数我的稍微补充一下,原型如下:
  1. int atexit(void (*func)(void));   
   atexit 函数是标准 C 新增的。它“注册”一个函数,使这个函数将在 exit 函数被调用时或者当 mian 函数返回时被调用。当程序异常终止时(例如调用 abort 或 raise),通过它注册的函数并不会被调用。编译器必须至少允许程序员注册32个函数。如果注册成功,atexit 返回0,否则返回非零值。没有办法取消一个函数的注册。在 exit 所执行的任何标准清理操作之前,被注册的函数按照与注册顺序相反的顺序被依次调用。每个被调用的函数不接受任何参数,并且返回类型是 void。被注册的函数不应该试图引用任何存储类别为 auto 或 register 的对象(例如通过指针),除非是它自己所定义的。多次注册同一个函数将导致这个函数被多次调用。有些传统 C 编译器用 onexit 这个名称实现了像是的功能。
   atexit是注册后进先出的函数,和函数入栈出栈是一样的。
   在这里注册了四个函数,理解为入栈的顺序为fn1() -> fn2() -> fn3() -> fn4();出栈的顺序正好相反,而什么时候出栈呢?就是在调用函数结束时,准确的说应该是函数调用的最后的操作就是出栈过程。main()同样也是一个函数,在结束时,按出栈的顺序调用四个函数,即为fn4() -> fn3() -> fn2() -> fn1();

   注册这个函数的目的就是为了在函数退出时调用的,即使是main()函数也是这样的。可以在这些函数中加入一些清理工作,比如内存释放等等。

出处:http://blog.youkuaiyun.com/huang_xw/article/details/8542105

<think>根据用户需求,我们需要在之前提供的代码基础上,补充定义main函数,使得程序结构更完善。程序将从一个文本文件中读取内容,然后提取所有以"https://"开头的URL地址,并将结果输出。 步骤: 1. 定义一个函数`extract_https_urls(text)`,用于从文本中提取URL。 2. 在main函数中,读取指定的文本文件(例如,用户可以通过命令行参数指定文件,或者固定文件名)。 3. 调用`extract_https_urls`函数提取URL。 4. 打印提取到的所有URL。 注意:这里我们假设文本文件路径通过命令行参数传入。如果没有提供参数,则使用默认文件名或提示用户。 我们将使用`sys.argv`来获取命令行参数。如果提供了参数,则第一个参数作为文件名;否则,可以提示错误或使用默认文件名(这里我们要求必须提供文件名)。 代码结构如下: ```python import re import sys def extract_https_urls(text): pattern = r'https://\S+' urls = re.findall(pattern, text) return urls def main(): # 检查命令行参数 if len(sys.argv) < 2: print("请提供文本文件路径作为参数。") sys.exit(1) file_path = sys.argv[1] try: with open(file_path, 'r', encoding='utf-8') as file: text = file.read() except Exception as e: print(f"读取文件时出错: {e}") sys.exit(1) urls = extract_https_urls(text) if urls: print("提取到的URL地址:") for url in urls: print(url) else: print("未找到https://开头的URL地址。") if __name__ == "__main__": main() ``` 说明: 1. 使用`sys.argv`获取命令行参数,第一个参数(索引0)是脚本名,第二个参数(索引1)是文件名。 2. 使用`with open`打开文件,并指定编码为utf-8(可根据实际情况调整)。 3. 调用提取函数并打印结果。 注意:如果URL后面紧跟着标点符号(例如逗号、句号),上述正则表达式可能会包含这些符号。为了避免这种情况,我们可以优化正则表达式,使用一个更精确的模式:`r'https://[^\s<>"\'()]+'`,但这样可能会过于复杂。考虑到用户需求是提取https://开头的URL,且要求前后其他文本不要,我们暂时使用`\S+`,因为它简单且覆盖大多数情况。如果用户需要更精确的提取,可以进一步调整。 但是,根据引用[1][2][3][4]的内容,用户可能还关心如何下载这些URL对应的文件。不过当前问题仅要求提取URL,因此我们只完成提取部分。 如果用户需要处理URL末尾的标点,我们可以使用以下优化:在模式后面添加一个非捕获组来排除常见的标点,例如:`r'https://[^\s<>]+'`,但这样可能会排除掉URL中允许的字符(比如路径中的括号)。因此,我们暂时不处理,如果用户有进一步需求,可以在相关问题中提出。 现在,我们提供完整的代码,用户可以直接保存为Python脚本并运行。 例如,将脚本保存为`extract_urls.py`,然后在命令行运行: ``` python extract_urls.py input.txt ``` 其中`input.txt`是包含文本的文件。 相关问题: 1. 如何同时提取 "http://" 和 "https://" 开头的URL? 2. 如何避免提取到的URL包含末尾的标点符号(如逗号、句号)? 3. 如何将提取到的URL保存到文件中?</think>以下是根据您的需求实现的Python代码,包含完整的main函数结构,用于从文本文件中提取所有以"https://"开头的URL地址: ```python import re import sys def extract_https_urls(text): """ 从文本中提取所有以 "https://" 开头的URL地址 参数: text (str): 输入文本 返回: list: 提取到的URL列表 """ pattern = r'https://\S+' urls = re.findall(pattern, text) return urls def main(): """主函数,处理文件输入和结果输出""" # 检查命令行参数 if len(sys.argv) != 2: print("使用方法: python extract_urls.py <输入文件>") print("示例: python extract_urls.py input.txt") sys.exit(1) input_file = sys.argv[1] try: # 读取文件内容 with open(input_file, 'r', encoding='utf-8') as file: text_content = file.read() # 提取URL urls = extract_https_urls(text_content) # 输出结果 if urls: print("提取到的URL地址:") for url in urls: print(url) else: print("未找到https://开头的URL地址") except FileNotFoundError: print(f"错误: 文件 '{input_file}' 未找到") except Exception as e: print(f"处理文件时出错: {e}") if __name__ == "__main__": main() ``` ### 使用说明: 1. 将上述代码保存为`extract_urls.py` 2. 在命令行中行: ```bash python extract_urls.py 输入文件.txt ``` 3. 程序会输出所有找到的https://开头的URL地址 ### 功能特点: 1. **完整的main函数结构**:包含参数检查、文件读取和结果输出 2. **错误处理**:处理文件不存在和其他异常情况 3. **命令行参数**:通过命令行指定输入文件 4. **UTF-8编码支持**:正确处理中文和其他特殊字符 5. **正则表达式优化**:使用`\S+`匹配完整的URL地址 ### 示例: 假设`input.txt`内容为: ``` 访问我们的网站:https://www.example.com 资源下载:https://download.example.com/file.zip 无效链接:http://insecure-site.com ``` 运行命令: ```bash python extract_urls.py input.txt ``` 输出: ``` 提取到的URL地址: https://www.example.com https://download.example.com/file.zip ``` ### 注意事项: 1. 如果URL后紧跟标点符号(如句点或逗号),可能会包含在提取结果中 2. 程序只提取以`https://`开头的URL,不包含`http://`或其他协议 3. 确保输入文件使用UTF-8编码,否则可能无法正确处理特殊字符
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值