如何启用将文件拖动到*.exe并将其作为参数获取的功能?

7

我该怎么做,让我的程序使用拖放到其图标上的文件作为参数?

我的当前main方法如下:

int main(int argc, char* argv[])
{
    if (argc != 2) {
        cout << "ERROR: Wrong amount of arguments!" << endl;
        cout << "\n" << "Programm closed...\n\n" << endl;
        exit(1);
        return 0;
    }

    Converter a(argv[1]);
    // ...

    cout << "\n" << "Programm finished...\n\n" << endl;

    // cin.ignore();
    return 0;
}

我希望能够选择10个(左右)文件,将它们拖放到EXE上,并在我的应用程序中处理它们。
编辑: 传入的参数被用作文件名,在构造函数中构建。
Converter::Converter(char* file) {
       // string filename is a global variable
   filename = file;
   myfile.open(filename.c_str(), ios_base::in);
}

读取文本文件的方法:

string Converter::readTextFile() {
char c;
string txt = "";

if (myfile.is_open()) {

    while (!myfile.eof()) {
        myfile.get(c);
        txt += c;
    }

} else {
    error("ERROR: can't open file:", filename.c_str());
}
return txt;
}

编辑2: 已删除

更新:
我又回到了这个点。

实际的Main方法:

// File path as argument

int main(int argc, char* argv[]) { 如果 (argc < 2) { cout << "错误:参数数量不正确!请至少提供一个参数...\n" << endl; cout << "\n" << "程序已关闭...\n\n" << endl; cin.ignore(); exit(1); return 0; } }

该代码段是一个C++程序的主函数。它检查是否有足够的参数传递给程序。如果没有,程序将输出错误消息并关闭。否则,程序将继续执行。
vector<string> files;

for (int g = 1; g < argc; g++) {
    string s = argv[g];
    string filename = "";
    int pos = s.find_last_of("\\", s.size());

    if (pos != -1) {
        filename = s.substr(pos + 1);

        cout << "argv[1] " << argv[1] << endl;
        cout << "\n filename: " << filename << "\n pos: " << pos << endl;
        files.push_back(filename);

        }
    files.push_back(s);
    }

for (unsigned int k = 0; k < files.size(); k++)
    {
    cout << "files.at( " << k << " ): " << files.at(k).c_str() << endl;
    Converter a(files.at(k).c_str());
    a.getATCommandsFromCSV();
    }


cout << "\n" << "Programm finished...\n\n" << endl;

cin.ignore();

return 0;
}

实际上,控制台窗口只会出现大约0.5秒并再次关闭。
它没有停留在任何一个 cin.ignore(); 也许它根本没到那里?

有人能帮忙吗?


请看下面的答案,如有任何相关问题,请随时问。 - jave.web
我曾经遇到过类似的问题。在迭代参数的循环之前,我添加了 std::cout << "pause";,不知何故它就开始工作了。 - feos
3个回答

18

除了处理命令行参数外,您的程序不需要做任何特殊的事情。当您将文件拖放到资源管理器中的应用程序上时,它只是将文件名作为参数传递给程序。多个文件也是如此。

如果您只期望得到一个文件名列表,则只需遍历所有参数,对其执行所需操作,然后完成即可。这适用于零到几乎任意数量的参数。


我尝试了只使用一个文件,但什么也没发生...程序(控制台窗口)出现了不到1秒钟,什么也没有发生。相比之下,手动通过控制台输入参数可以正常工作。这就是为什么我在问的原因... - Beasly
@Beasly:你应该意识到,控制台窗口会在程序运行结束后立即消失。加入一个暂停或等待按键操作,这样你就可以看到输出结果了。 - Joey
是的,我会 ;) 问题在于,我操作一个文本文件并将其另存为另一个名称。例如:输入:test.txt 输出:text_c.txt - 实际上这个文件并不存在。正如我所说,手动操作可以解决问题... - Beasly
@Beasly:本质上,我想你需要支持两种情况:1. 参数只是一个相对路径到文件(或者只是文件名),这种情况下你可能需要将其与当前工作目录解析。2. 参数是一个绝对路径到文件,这种情况下你可能只想更改输出文件的文件名而不是整个路径。 - Joey
程序现在停止了...我正在努力中...一有结果就会发布我的进展。 - Beasly
显示剩余5条评论

3
也许你可以编写一个如下的测试程序:
int main(int argc, char* argv[])
{
    // argv[0] is not interesting, since it's just your program's path.
    for (int i = 1; i < argc, ++i)
        cout << "argv[" << i << "] is " << argv[i] << endl;

    return 0;
}

看看在你将不同的文件扔给它后会发生什么。


编辑:只需看看Joey的答案。


从我的回答评论中可以看出,我们现在正处于这个点上:编写一个输出参数的测试程序;-) - Joey

1

主要问题的答案

要查看您上一个问题的答案,请参见本回答底部

所有拖放的文件都可以作为argv [orderOfTheFile] orderOfTheFile 从1-n),得到,
然而,Windows如何创建该顺序,现在那才是真正的谜团...

无论如何,假设我在桌面上创建了26个纯文本文件(*.txt),从a.txtz.txt
如果我将它们拖放到位于C:\驱动器上的ArgsPrinter_c++.exe上,
输出将类似于这样:

argc = 27
argv[0] = C:\ArgsPrinter_c++.exe
argv[1] = C:\Users\MyUserName\Desktop\c.txt
argv[2] = C:\Users\MyUserName\Desktop\d.txt
argv[3] = C:\Users\MyUserName\Desktop\e.txt
argv[4] = C:\Users\MyUserName\Desktop\f.txt
argv[5] = C:\Users\MyUserName\Desktop\g.txt
argv[6] = C:\Users\MyUserName\Desktop\h.txt
argv[7] = C:\Users\MyUserName\Desktop\i.txt
argv[8] = C:\Users\MyUserName\Desktop\j.txt
argv[9] = C:\Users\MyUserName\Desktop\k.txt
argv[10] = C:\Users\MyUserName\Desktop\l.txt
argv[11] = C:\Users\MyUserName\Desktop\m.txt
argv[12] = C:\Users\MyUserName\Desktop\n.txt
argv[13] = C:\Users\MyUserName\Desktop\o.txt
argv[14] = C:\Users\MyUserName\Desktop\p.txt
argv[15] = C:\Users\MyUserName\Desktop\q.txt
argv[16] = C:\Users\MyUserName\Desktop\r.txt
argv[17] = C:\Users\MyUserName\Desktop\s.txt
argv[18] = C:\Users\MyUserName\Desktop\t.txt
argv[19] = C:\Users\MyUserName\Desktop\u.txt
argv[20] = C:\Users\MyUserName\Desktop\v.txt
argv[21] = C:\Users\MyUserName\Desktop\w.txt
argv[22] = C:\Users\MyUserName\Desktop\x.txt
argv[23] = C:\Users\MyUserName\Desktop\y.txt
argv[24] = C:\Users\MyUserName\Desktop\z.txt
argv[25] = C:\Users\MyUserName\Desktop\a.txt
argv[26] = C:\Users\MyUserName\Desktop\b.txt

我的ArgsPrinter_c++.exe源代码如下:
#include <iostream> 
using namespace std;

int main(int argc, char* argv[]) { 
   cout << "argc = " << argc << endl; 
   for(int i = 0; i < argc; i++) 
      cout << "argv[" << i << "] = " << argv[i] << endl; 

   std::cin.ignore();
   return 0; 
}

你的最后一个问题

我创建了一个简单的程序,只创建了你的类的框架以便使用,程序的主体本身运行得非常好 => 如果你的程序退出得太快,问题可能出现在你的类中...

测试源代码:

#include <iostream> 
#include <vector>
using namespace std;

class Converter{
    public: 
    Converter(const char* f){ cout << f << endl; }
    void getATCommandsFromCSV(){ cout << "called getATCommandsFromCSV" << endl; }
};

int main(int argc, char* argv[]) { 
  vector<string> files;

  for (int g = 1; g < argc; g++) {
      string s = argv[g];
      string filename = "";
      int pos = s.find_last_of("\\", s.size());

      if (pos != -1) {
          filename = s.substr(pos + 1);

          cout << "argv[1] " << argv[1] << endl;
          cout << "\n filename: " << filename << "\n pos: " << pos << endl;
          files.push_back(filename);

          }
      files.push_back(s);
      }

  for (unsigned int k = 0; k < files.size(); k++)
      {
      cout << "files.at( " << k << " ): " << files.at(k).c_str() << endl;
      Converter a(files.at(k).c_str());
      a.getATCommandsFromCSV();
      }

  cout << "\n" << "Programm finished...\n\n" << endl;

  cin.ignore();

  return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接