How would I go about these command line arguments?

Here is the problem:Extend your file comparison program in two ways. First, make it possible to specify the file names on the command line (5 points). Only ask the user for the file names when they are not specified (5 points). And support a command line flag to control the number of differences identified (5 points). Plus 5 points for overall structure and style. Usage should look like this:
differ -a file1.txt file2.txt
displays all differences
differ -n file1.txt file2.txt
displays the first n differences
And, for example
differ -20
displays the first 20 differences and prompts the user for the file names


And Here is my code thus far:
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
#include <iostream>
#include <fstream>
#include <string.h>
#include <stdio.h>

using namespace std;

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

string filetocompare1,filetocompare2;
fstream file1, file2;

for(int i = 0; i < argc; i++);
argc <= 3;

filetocompare1 = argv[1];
filetocompare2 = argv[2];

if(argc == 1)
{
cout << "What is the name of the second file you want to compare?\n";
cin >> filetocompare2;
}

if(filetocompare1 == "Mary1.txt" || filetocompare1 == "Mary2.txt" || filetocompare1 == "Bliss.txt" || filetocompare1 == "Hay.txt" || filetocompare1 == "Nicolay.txt" || filetocompare1 == "Bancroft.txt")
{
file1.open(filetocompare1.c_str());
}
else
{
cout << "Error.\n";
cout << "Your first file is short.";
return 0;

}

if(filetocompare2 == "Mary1.txt" || filetocompare2 == "Mary2.txt" || filetocompare2 == "Bliss.txt" || filetocompare2 == "Hay.txt" || filetocompare2 == "Nicolay.txt" || filetocompare2 == "Bancroft.txt")
{
file2.open(filetocompare2.c_str());
}
else
{
cout << "Error.\n";
cout << "Your second file is short.";
return 0;
}

if(filetocompare1 == filetocompare2)
{
cout << "Files are identical.\n";
return 0;
}
else
{
char string1[256], string2[256];
int i; i = 0;

while(!file1.eof())
{
file1.getline(string1,256);
file2.getline(string2,256);
i++;
if(strcmp(string1,string2) != 0)
{
cout << i << "-The strings are not equal" << "\n";
cout << " " << string1 << "\n";
cout << " " << string2 << "\n";
}
}
return 0;
}
}



How would I go about solving this?
Hi nahla,

Please post your compiler output in full
Your solution seems to be a mix of C and C++. Try to move towards the C++ way of doing things.

Here is a tutorial on argc argv:

http://crasseux.com/books/ctutorial/argc-and-argv.html


In there you will see that argc is always at least 1.

1
2
for(int i = 0; i < argc; i++);
argc <= 3;



You have a semiclon after the for loop, which isn't needed. That draws a warning from my compiler.
the next line doesn't make sense - did you mean an if statement?

Lines 17 & 18 happen before any error testing of the arguments is done. What if no args were given?

Line 26 is a nightmare and not scalable - what if there were 20 files? Much better to do this with a switch statement.

LIne 64: If you are using C++, you can use C++ strings, rather than than the C approach of array of char,
C++ strings are handy - you can compare them directly with == . So no need to use the C function strcmp.

Line 49: this will not work because the variables are arrays of char not strings.


When you open files, check that it worked - don't just assume that it does. Programming is all about thinking "What can go wrong" and providing code to minimise problems.

I look forward to helping out further. :)
If you can help me out I am trying to get this done within an hour and a half.

I have not yet improved my code to follow the problem guidelines because I am completely lost as how to go about structuring my program to follow the guidelines.

Line 26 is meant to just reference my text files.

I am really really lost! Some help with the code and explanation would be awesome! I've already gone this far in my study problems and now I am stuck.
So have you fixed up the problems I mentioned?

I am not going to write code for you - that is your job, I will provide hints as I have done in my last post.

Edit: IF you were worried about time - you should have been on it earlier - not 2 hours before it is due.
Last edited on
Not necessarily due. Here is some code I am currently trying to implement into my code above, I keep receiving several errors when compiling, I just opened up a new text file and started researching different parts:

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
int main(int argc, char* argv[])
{  
   bool decrypt = false;
   int key = 3;
   int nfile = 0; // The number of files specified
   ifstream infile;
   ofstream outfile;
          
   if (argc < 3 || argc > 5) usage(string(argv[0]));  //  wrong number of arguments

   int i;
   for (i = 1; i < argc; i++)     // process each argument
   {  
      string arg = string(argv[i]);  // converts C style string to C++ style string
      if (arg.length() >= 2 && arg[0] == '-') // It is a command line option
      {  
         char option = arg[1];  // character following the -
         if (option == 'd')     // alternately if (arg[1]=='d')
         decrypt = true;
         else if (option == 'k')
         key = string_to_int(arg.substr(2, arg.length() - 2));
         // alternately, use 
         //key = atoi(argv[i]+2);  // C style strings
      }
      else  // Not a command line option but a file name
      {  
         nfile++;
         if (nfile == 1)  // First file name
         {  
            infile.open(arg.c_str());
            if (infile.fail()) open_file_error(arg);
         }
         else if (nfile == 2) // Second file name
         {  
            outfile.open(arg.c_str());
            if (outfile.fail()) open_file_error(arg);
         }
      }
   }

   if (nfile != 2) usage(string(argv[0]));  // incorrect number of files

   if (decrypt) key = -key;

  //   encrypt_file(infile, outfile, key);

   int lines = 0;
   string S;
   while (getline(infile,S)) lines++;
cout << lines << "\n";
   infile.close();
   outfile.close();
   return 0;
}



If you have compile errors - then post them

line 9: Presumably the usage function is written somewhere else. It is not declared (that I can see - you haven't shown all the code)so that is an error

argv[0] is the program name, which assigned to arg[0] - so line 15 won't work. Did you read the article in the link I provided?

Processing command line args is a bit involved, the thing is to decide on a list of valid argument combinations, then work form there.

The other thing is - do you know how to use the debugger? If you are using an IDE it should be easy.

Using the debugger is by far the easiest way to solve problems IMO.
This is what I am most confused about, is the directions to the problem. How exactly do I set up command line arguments in order to have usage such as 'differ -a file1.txt file2.txt
displays all differences' ? I am comparing two different text files, and am lost on how to do this. If you could provide some explanation with code (not necessarily using my code, but maybe a template with some information on what it means) that would be of the most help. I am trying to learn the mechanics of this, and I understand some of it, but the directions prompted to me are really confusing to me.
differ -a file1.txt file2.txt


Ok, if this is one of the valid argument lists.

argc == 4

argv[0] == differ
argv[1] == -a
argv[2] == file1.txt
argv[3] == file2.txt


First check there are the right amount of arguments. You can use a switch statement to help with this.

case argc is 1 -> error call usage function
case argc is 2 -> error call usage function
case argc is 3 -> no -a arg - just 2 filenames, or -a and 1 filename -> error
case argc is 4 -> what we want, but check for errors still.
case default -> error call usage function


Then go through each arg and check it is OK, set variables, do the rest of the processing.

You will need to make good use of functions to do this.

Last edited on
Topic archived. No new replies allowed.