【问题标题】:Passing text file instead of user input as command line argument将文本文件而不是用户输入作为命令行参数传递
【发布时间】:2018-04-04 20:57:51
【问题描述】:

我试图弄清楚如何能够将 .txt 文件作为命令提示符参数而不是用户输入来读取。如果我有程序

#include <iostream>
#include "cmdline.h"
using namespace std;

int main (int cnt, char * args[]) {
    int a = cmdline_int(args, 1);
    int b = cmdline_int(args, 2);
    cout << "sum = " << a << " + " << b << " = " << a + b << endl;
    return 0;   
}

文件“cmdline.h”包含在哪里

#include <cstdlib>
#include <string>
using namespace std;

int cmdline_int( char* cmdline_a[], int n ) {
  return atoi( cmdline_a[ n ] );
}
char cmdline_char( char* cmdline_a[], int n ) {
  char c = cmdline_a[ n ][0];
  return c;
}

我可以运行程序

./program 3 5

输出将是

总和 = 3 + 5 = 8

但是,如果我有一个文件 (textfile.txt) 仅包含列表形式的相同数字,即

3
5

并尝试将其运行为

./program

我明白了

分段错误

如果 textfile.txt 包含“3 5”,它会做同样的事情,尽管无论如何我使用列表形式的文本文件很重要。我需要更改什么以使“./program textfile.txt”具有与“./program 3 5”相同的输出?
我猜问题出在 int 主括号之间,我只是不确定具体是什么。

【问题讨论】:

    标签: c++ command-line-arguments


    【解决方案1】:

    您将 textfile.txt 重定向到您的程序中,因此您无法直接从参数中读取它。

    您可以使用 cin 从重定向中读取文件内容

    char c;
    while (std::cin.get(c))
    {
        // process char
    }
    

    或者,您可以将文件名作为参数传递,例如 ./program textfile.txt,然后从文件中读取

    char* filename = args[1];
    std::ifstream infile(filename);
    int a = 0, b = 0;
    infile >> a >> b;
    

    【讨论】:

    • 对于第一部分,在“while”下我是否仍然使用 cmdline_int(args,#) 部分?我也不熟悉 ifstream 和 infile() 因此我不允许使用它们(我知道,非常严格,抱歉)。输入确实必须遵循格式 ./program
    【解决方案2】:

    运行你的程序:

    ./program myfile.txt
    

    并使用argv[1] 命令行参数来接受文件名。相应地解析:

    #include <iostream>
    #include <fstream>
    #include <string>
    
    int main(int argc, char* argv[]) {
        if (argc > 1) {
            std::ifstream fs(argv[1]);
            int a, b;
            while (fs >> a >> b) {
                std::cout << a << ' ' << b << '\n';
            }
        } else {
            std::cout << "No arguments." << '\n';
        }
    }
    

    【讨论】:

    • 除了使用“ifstream”之外,还有其他选择吗?我还没有学过,因为这是一门课,所以我不能使用我们在技术上还没有学过的任何东西。还有,什么是 fs()?我也不熟悉
    • @zeurosis 还有其他选择。这是读取文件内容的惯用方式。我已经用相关标题更新了答案,供您探索。
    【解决方案3】:

    测试程序

    当您想检查此类内容时,我建议您首先了解应用程序如何接收它们。我将从以下最小程序开始:

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

    然后执行

    • ./program 3 5 输出:

      ./program
      3
      5
      
    • ./program &lt; textfile.txt 输出:

      ./program
      

    所以现在您可以看到问题在于如何将txt 文件传递​​给应用程序。而您的应用程序崩溃的原因是因为您使用了参数而没有验证它们是否确实存在!

    说明

    符号 (

    ./program &lt; textfile.txt 与参数无关,您必须从cin 读取它。

    使用参数的解决方案

    使用

    ./program `cat textfile.txt`
    

    cat 命令将用文件的内容“替换自己”,它就像您手动编写的一样工作。

    使用

    使用./program &lt; textfile.txt 运行时,以下将打印数字:

    int a, b;
    cin >> a >> b;
    cout << a << endl;
    cout << b << endl;
    

    组合解决方案

    这对双方都有效:

    int main (int argc, char * argv[]) {
      int a, b;
      if (argc == 1) { // No extra arguments, read from cin
        cin >> a >> b;
      } else { // Use args
        a = cmdline_int(argv, 1);
        b = cmdline_int(argv, 2);
      }
    
      // Do something with a,b
      return 0;
    }
    

    【讨论】:

    • 有什么我可以改变的,所以“./program
    • @zeurosis,我添加了关于“
    【解决方案4】:
    #include <stdio.h>
    int main(int argc, char* argv[]) {
      *//read from textfile one char at a time:*
      char c;
      while ((c=getchar()) != EOF){ 
         *//Command line should look like:
         //./program < textfile.txt*
        printf("%c",c); //print char 
      }
      return 0;
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-17
    • 2013-05-18
    • 2018-02-09
    • 2012-12-21
    • 2015-09-12
    • 2010-09-16
    • 1970-01-01
    • 2019-04-19
    相关资源
    最近更新 更多