Command Line Arguments

I am being asked to use command line arguments and read from files for the first time. I wrote the code the best I know how to calculate a least squares linear regression line. I think it is correct but now I have to change it so that instead of prompting the user for input, the program takes a single command line argument containing the name of a file. The file then contains two doubles on each line, separated by a space, with the first representing an x value and the second representing a y value. I need to use these values to form my vectors of x and y observations. The program should report all of the same
analysis as the original program.

I am really lost about where to start with making the changes. Do I need to change things outside of the main function? I know I need to add the following to the main statement but after that I am confused.

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <iomanip>
using namespace std;

double sum(vector<double> a)
{
    double s = 0;
    for (int i = 0; i < a.size(); i++)
    {
        s += a[i];
    }
    return s;
}

double mean(vector<double> a)
{
    return sum(a) / a.size();
}

double sqsum(vector<double> a)
{
    double s = 0;
    for (int i = 0; i < a.size(); i++)
    {
        s += pow(a[i], 2);
    }
    return s;
}

double stdev(vector<double> nums)
{
    double N = nums.size();
    return pow(sqsum(nums) / N - pow(sum(nums) / N, 2), 0.5);
}

vector<double> operator-(vector<double> a, double b)
{
    vector<double> retvect;
    for (int i = 0; i < a.size(); i++)
    {
        retvect.push_back(a[i] - b);
    }
    return retvect;
}

vector<double> operator*(vector<double> a, vector<double> b)
{
    vector<double> retvect;
    for (int i = 0; i < a.size() ; i++)
    {
        retvect.push_back(a[i] * b[i]);
    }
    return retvect;
}

double sample_correlation(vector<double> X, vector<double> Y)
{
    return sum((X - mean(X))*(Y - mean(Y))) / (X.size()*stdev(X)* stdev(Y));
}

int main() {
    /* Enter your code here. Read input from STDIN. Print output to STDOUT */
    vector<double> xobs;
    vector<double> yobs;
    int i = 1;
    double entry;
    
    cout<< "Enter the real x,y series (alternating) with each entry separated by a space. Enter a character to end seq. " <<endl;
    while(cin>>entry)
    {
        if (i%2 != 0) {
            xobs.push_back(entry);
            ++i;}
        else{
            yobs.push_back(entry);
            ++i;}
    }
    
    if (xobs.size() == 0 || xobs.size() == 1){
        cout << "Sample size too small." <<endl;
    }
    
    cout << fixed << setprecision(3) << sample_correlation(xobs, yobs) << endl;
    
    return 0;
}
You need to check if a filename was supplied
1
2
3
4
5
6
7
8
9
10
11
int main(int argc, char* argv[])
{
  if argc != 2)
  {
    // show error msg - like usage program.exe filename
   return 1;
  }
  // filename in argv[i]
  ifstream(argv[1]);
  // check if stream is valid and load data if it is or sgow error msg
}
Unrelated note: IF line 83 was true THEN what happens on line 87?
Do I need to change things outside of the main function? I know I need to add the following to the main statement but after that I am confused.
 
int main(int argc, char* argv[]){***}


Only main() will need to be changed, the rest of the code remains as it is.

Start by familiarising yourself with the command-line arguments. Sample program
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

using namespace std;

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

If you compile and run that, it should output a line starting with 0 and then the path/name of the program itself. If you run the program from the command line, you can type whatever arguments you like after the program name.

Assume your program is named test.exe, and you type
test.exe hello world

Then the output should be something like this:
0  test.exe
1  hello
2  world


In order to use it to get the file name, the program might look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char * argv[])
{
    // check that argument is present
    if (argc < 2)
    {
        cout << "Missing filename argument\n";
        return 1;
    }
    
    // try to open the file
    ifstream fin(argv[1]);
    if (!fin)
    {
        cout << "Could not open file: " << argv[1] << '\n';
        return 1;
    }
     
     
    // read pairs of doubles from the file 
    double x, y;
    
    while (fin >> x >> y)
    {
        cout << "x = " << x << "    y = " << y << '\n';
     
    } 
     
}

Registered users can post here. Sign in or register to post.