-13

我做了一个简单的测试程序来玩 C++11 线程。

#include <iostream>
#include <stdlib.h>
#include <thread>
using namespace std;

void tee(int civ)
{
    for(int loop=0; loop<19; loop++, civ++)
    {
        civ = civ%19;
        cout << loop << "\t" << civ << endl;
        this_thread::sleep_for(chrono::milliseconds(300));
    }
}

void koot()
{
    while(true)
    {
        cout << ":) ";
        this_thread::sleep_for(chrono::milliseconds(300));
    }
}

int main(int argc, char *argv[])
{
    thread saie(tee, atoi(argv[1])),
        kamaa(koot);
    saie.join();
    kamaa.join();

    return 0;
}

只要我提供命令行参数,它就可以正常工作,但如果我不提供,它就会崩溃。如何解决?我尝试检查参数计数,如果它们存在,则无济于事。

编辑:我不得不添加这一行:

if(argc < 2) return 1;
4

4 回答 4

7

它崩溃是因为您正在访问

argv[1]

如果有的话,它将保存一个命令行参数(除了程序的名称)。你应该检查是否argc大于1。为什么大于1?因为第一个命令行参数是程序本身的名称。所以argc总是大于0。并且索引从0. 所以如果argc == 1, onlyargv[0]是有效的。

#include <iostream>
int main(int argc, char* argv[])
{
  // no need to check argc for argv[0]
  std::cout << argc << " " << argv[0] << "\n";
}
于 2013-01-18T17:49:34.937 回答
4

argv[1]为空,导致调用atoi(). 请注意,C++ 中的数组索引是从零开始的!

于 2013-01-18T17:48:46.363 回答
3

因为您不检查是否argc > 1并尝试访问argv[1]

解决这个问题的方法是首先检查是否argc > 1然后访问 argv[1]。

int main(int argc, char *argv[])
{

    if(argc > 1){
    thread saie(tee, atoi(argv[1])),
        kamaa(koot);
    saie.join();
    kamaa.join();
   }
    return 0;
}

要记住的要点:

  1. argc默认情况下为 1。这是保存编号的参数计数器。传递给程序的参数。默认情况下,它的 1 因为程序获取可执行文件的名称(和路径)

  2. argv保存以 NULL 结尾的字符数组(或字符串)的数组。argv[0]将始终保存可执行文件的名称。

  3. 永远不要假设用户总是会输入参数。并且在将来访问argv或任何数组时始终进行边界检查。

于 2013-01-18T17:48:53.770 回答
2

请尝试以下代码:

int main(int argc, char *argv[])
{
    if(argc < 2) {   cout<<"No command line arguments found\n Aborting!\n"; return 1;}
    else         {   thread saie(tee, atoi(argv[1])),kamaa(koot);}
    saie.join();
    kamaa.join();

    return 0;
}

您正在尝试访问不存在的命令行参数 argv[1]。最好检查命令行参数是否存在。

于 2013-01-18T17:57:44.563 回答