C++ 从命令行参数打开文本文件

C++ 从命令行参数打开文本文件,c++,text-files,command-line-arguments,ifstream,C++,Text Files,Command Line Arguments,Ifstream,我试图从命令行参数打开一个文件 我已经调试了我的程序: 当我打印file的值时,它给出了值 当我打印argv的值时,它给出值char**0x7fffffffe4e0 当我打印argv[1]的值时,它给出了值0x0 该函数无法打开我的文件。不知道为什么 我试过: 如果file.u也打开,则会出现相同的问题 在我的主要职能中,我通过: buildBST(&argv[1]); BSTTreeData buildBST (char *argv[]){ vector <string&g

我试图从命令行参数打开一个文件

我已经调试了我的程序:

当我打印file的值时,它给出了值

当我打印argv的值时,它给出值char**0x7fffffffe4e0

当我打印argv[1]的值时,它给出了值0x0

该函数无法打开我的文件。不知道为什么

我试过:

如果file.u也打开,则会出现相同的问题

在我的主要职能中,我通过:

buildBST(&argv[1]);

BSTTreeData buildBST (char *argv[]){
  vector <string> allwords;

  BSTTreeData Data;
  BinarySearchTree<string> Tree;

  ifstream file (argv[1]);

  char token;

  string listofchars = "";
  string input;

  int distinct = 0;
  int line = 1;

  if (file){
      //if the file opens
      while (getline(file, input)) //gets every line in the file
      {
          for (int i = 0; i < input.size(); ++i) //gets all the contents in the line
          {
              token = input[i]; //each character become a 'token'
              if (isalpha(token))
              {
                  //if the character is an alphabetical character
                  listofchars += token; //append character to a string
                  if (Contains(allwords, listofchars) == false)
                  {
                  //if the current word has not already been added to vector of words
                      //increment the distinct word count
                      distinct += 1;
                      Tree.insert(listofchars); //creates the BST
                      allwords.push_back(listofchars); 
                      //add current word to vector of all the words
                  }
                  else
                  line++; //increments the line number
              }
              else
                  line++; //increments the line number
          }
          listofchars = ""; //creates empty character string
      }
    }
    file.close(); //closes file

    Data.BST = Tree;
    Data.linenumber = line;
    Data.distinctwords = distinct;
    Data.words = allwords;
    return Data;
}

回想一下,在大多数操作系统中,主函数中的argv是以下形式的数组:

argv[0]        = /* path to the program ("zeroth argument") */;
argv[1]        = /* first argument */;
argv[2]        = /* second argument */;
...
argv[argc - 1] = /* last argument */;
argv[argc]     = NULL;
这里的问题是你看到的是第二个论点,而不是第一个。在main函数中调用buildBST&argv[1]时,将指针移动一个元素,以便在buildBST中argv现在指向第一个参数而不是第零个参数,因此buildBST中的表达式argv[1]生成第二个参数而不是第一个参数

解决办法是:

将&argv[0]或等效地传递给buildBST,然后使用argv[1]获取参数,或

将&argv[1]或等效的argv+1传递到buildBST中,然后使用argv[0]获取参数


第一种方法可能更具可读性,因为您没有改变argv的含义。

如果argv[1]为NULL,那么问题在于您没有将文件名作为第一个参数传递。如何运行该程序?我使用“g++-g-std=c++11 myfile.cpp”编译并执行“/a.out test.txt”等等,您将&argv[1]传递给buildBST,这意味着buildBST中的argv参数现在指向第一个参数。这意味着buildBST中的argv[1]引用的是第二个参数,而不是第一个!请记住,C中的索引是以零为基础的。好的,这是有意义的。那么您的意思是,在我的主要任务中,我应该将argv[0]传递给buildBST?并同时更改“ifstream文件argv[0];”?arg[0]通常包含应用程序的路径,而不是传递给它的第一个参数,即/bin/appname。我认为第二种方法最好,因为您只需将argv[2]传递到函数中,就可以重用代码。当然,我也不会传递数组,只传递指向字符串的指针。您也可以这样做,但正如您所说,在这种情况下,您不应该首先传递字符**,当然也不应该标记变量argv。在我这样做之后,我得到一个控件可能会到达非void函数error的结尾。您是否忘记放置返回XXX;在某处