Write a new program called paginate.cc. It should work like this:
Usage: paginate file [...]

Required command line parsing: The options may be given in any order, but
must all precede the file(s) to be printed. Parsing the argument should simply
deposit the associated value in an appropriate variable that was previously
initialized to the program's defaults, specified below. Be careful not to read past
the end of argv[] even when the user enters a bogus command, like "paginate --
lines-per-page" (with no further arguments).

--I'm pretty sure my professor wants me to read in those arguments and separate the integer before lines-per-page//columns-per-page//tabstop and then based upon the string following the int, assign the int to the appropriate variable.

My question is how would i separate the string and the integer the user puts into argv, I'm sure ill have more problems as i get further into the program as well

Recommended Answers

All 6 Replies

In the two arguments to main(), argc is the number of arguments (command line arguments are separated by spaces or tabs), and argv is an array of the strings. So if you type this myprog --lines-per-page 30 argc will be 3 and argv will be
argv[0] = program name
argvp[1] = "--lines-per-page"
argv[2] = "30"

You don't really have to separate the strings because the C/C++ language startup code will do that for you.

Ok, i didnt fully understand my professors formatting for the input, but i understand it now. I have this code but for some reason the output prints what should be the header to each new page multiple times before it prints what is on the page.

in other words for this input:
./a.out --lines-per-page 2 hw3file.txt

this is my output:
Filename: --lines-per-page Page #1

Filename: 2 Page #1

Filename: hw3file.txt Page #1

1 Hello My Name is Dewey
2 blah blah
3 C++ is fun
4 whats up
5 hello
6 goodbye

This should be my output:
Filename: hw3file.txt Page #1

1 Hello My Name is Dewey
2 blah blah
Filename: hw3file.txt Page #2

3 C++ is fun
4 whats up
Filename: hw3file.txt Page #3

5 hello
6 goodbye

#include <string>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <stdlib.h>

using namespace std;

int main( int argc, char *argv[])
{
  string temp;
  int linenum = 1;
  int itemp;
  int lines = 0;
  int columns = 0;
  int page = 1;

  for( int i = 1; i < argc; i++ ){
    if( argv[i] == "--lines-per-page" && i + 1 <= argc ){
      i++;
      lines = atoi( argv[i] );
      i++;
    }
    if( argv[i] == "--columns-per-page" && i + 1 <= argc ){
      i++;
      columns = atoi( argv[i] );
      i++;
    }

    if( lines == 0 )
      lines = 24;
    if( columns == 0 )
      columns = 80;

    cout << "Filename: " << argv[i] << "     Page #" << page << "\n\n"; 

    ifstream inFile( argv[i] );

    while( getline( inFile, temp )){
      if( linenum > lines ){
	page++;
	cout << "Filename: " << argv[i] << "     Page #" << page << "\n\n"; 
      }

      cout << setw( 8 ) << left << linenum;
      cout << temp << "\n";
      linenum++;
    }
  }
  return 0;
}

p.s.

this is the full description of what i need to do
Required pagination functionality: Paginate the given file(s) to standard output,
including fixed-width line numbers, as in the previous homework. The command
line arguments specify the number of rows and/or columns on the physical page;
the defaults are 24 and 80, respectively. Each page of output should begin with
an informative header line showing at least the file name and page number,
followed by a blank line. The line numbers should be cumulative over the entire
input file, not reset at each new page.
Required modularity for the entire program: Try to keep each of your functions
within about 30-40 lines of code (a screenful, give or take). There is no reason to
use any global variables other than std::cout. Document each of your functions'
inputs, outputs, and behavior. Make your parameters const & whenever possible.

>>if( argv == "--lines-per-page"
C style strings can not be compared like that. You have to call strcmp() which is in string.h if( strcmp(argv[i],"--lines-per-page") == 0) >>&& i + 1 <= argc

You need to use the < operator, not <= operator. If (i+1) == argc then your program will access outside the valid bounds of the argv array.

>>int lines = 0;
>> int columns = 0;

>>the defaults are 24 and 80, respectively

Make the default value something much more reasonable, such as 24 lines per page and 80 columns per line. You don't want to see a report that has no lines or columns because its an infinite amount of blank pages.

Ok those things are fixed, but for some reason

lines = atoi

is not getting the integer value, instead it just sets lines equal to 0... so it will print the header after each line

this is my new output, the zero after the second header is the value of lines.

Filename: hw3file.txt Page #1

0Filename: hw3file.txt Page #2

1 Hello My Name is Dewey
Filename: hw3file.txt Page #3

2 How are you
Filename: hw3file.txt Page #4

3 C++ is fun
Filename: hw3file.txt Page #5

4 whats up
Filename: hw3file.txt Page #6

5 hello

My updated code is this

#include <string>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <stdlib.h>
#include <string.h>

using namespace std;

int main( int argc, char *argv[])
{
  string temp;
  int linenum = 1;
  int itemp;
  int lines = 24;
  int columns = 80;
  int page = 1;

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

    if( strcmp( argv[i], "--lines-per-page") && i < argc ){
      lines = atoi( argv[i + 1] );
      i += 2;
    }
    if( strcmp( argv[i], "--columns-per-page") && i < argc ){
      columns = atoi( argv[i + 1] );
      i += 2;
    }
    cout << "Filename: " << argv[i] << "     Page #" << page << "\n\n"; 
    cout << lines;

    ifstream inFile( argv[i] );

    while( getline( inFile, temp )){
      if( linenum > lines ){
	page++;
	cout << "Filename: " << argv[i] << "     Page #" << page << "\n\n"; 
      }

      cout << setw( 8 ) << left << linenum;
      cout << temp << "\n";
      linenum++;
    }
  }
  return 0;
}

>>for( int i = 0; i < argc; i++ ){
Start that loop at 1, not 0, because argv[0] is always the program name. So there is no use trying to test it.

>> if( strcmp( argv, "--lines-per-page") && i < argc ){

Two things wrong with that.
1) strcmp() returns 0 if the two strings are the same. so you need "== 0" in that statement
2) testing for i < argc is unnecessary because that is taken care of in the for statement
This is what you need: if( strcmp( argv[i], "--lines-per-page") == 0) { >>i += 2;
That is skipping too many values. just use ++i

Thanks Dragon, all fixed works perfectly now with a few more tweaks here and there

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.