argc是命令行参数个数,argv是参数字符串数组;argv[0]为程序路径,argv[1]起为用户参数;需先检查argc≥2再访问argv[1],避免空指针崩溃。

main函数里argc和argv到底是什么
argc是命令行参数个数,argv是这些参数组成的字符串数组,argv[0]固定是程序路径(不一定带完整路径,取决于怎么启动),从argv[1]开始才是用户真正传的参数。
常见错误是直接用argv[1]而没检查argc是否≥2,一运行就崩溃或读到空指针。C++标准规定argv[argc]必须为nullptr,但别依赖它做循环终止条件——先看argc更安全。
- argc最小值是1(只有程序名)
- argv里的每个元素都是
char*,不是std::string,要转得自己构造 - 参数里带空格?必须用引号包裹,shell才会当一个参数传进来,否则会被拆成多个argv项
把argv转成std::vector<:string>最稳妥写法
手写循环比用
int main(int argc, char* argv[]) {
std::vector<std::string> args;
for (int i = 1; i < argc; ++i) {
if (argv[i] != nullptr) {
args.emplace_back(argv[i]);
}
}
// 后续用args[0], args[1]...处理,安全
}别用std::vector<:string> args(argv + 1, argv + argc)</:string>——虽然能编译,但一旦argv里有nullptr(非标准但某些环境可能出),就会UB;而且不检查argv[i]是否为空,Windows下某些启动方式可能导致argv[1]为nullptr。
立即学习“C++免费学习笔记(深入)”;
处理带等号的参数比如--input=file.txt
这种不属于系统解析范畴,得自己切分。别用strtok,它会改原字符串;也别用std::string::find('=')后硬拆,得先确认等号是分隔符而非参数内容(比如文件名里真有=)。
- 典型场景:解析
--log=debug或-o output.bin - 推荐先判断argv[i]是否以
--或-开头,再按需处理后续项 - 用
std::string_view(argv[i]).substr(2)取长选项名,比std::string构造更轻量 - 如果参数值在下一个argv项(如
-f config.json),必须确保i+1 ,否则越界
Windows下宽字符(Unicode)参数怎么拿
cmd里输入中文路径或参数时,用传统main(int, char**)会乱码。必须用wmain配合wchar_t版本:
int wmain(int argc, wchar_t* argv[]) {
// argv现在是宽字符串,可直接用std::wstring处理中文
std::wstring program = argv[0];
// 注意:不能混用printf和wprintf,输出也要对应
}但链接器得设对:Visual Studio需在属性→高级→入口点填wmainCRTStartup;Clang/MSVC还要加/utf-8或确保源文件存为UTF-8 with BOM。否则即使写了wmain,argv里还是问号。
跨平台程序别指望一套代码通吃——Linux/macOS没wmain,Windows控制台默认编码又常是GBK,这个坑比想象中深。










