Thread: Inputting-Outputting specific areas of a file

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    122

    Inputting-Outputting specific areas of a file

    Okay, I have this program that needs to read in a file and output the contents in a file with specific parameters. The usage is as follows:

    Code:
    histogram.exe MaxPages inFileName outFileName
    where MaxPages is where the user says how many they want to see, inFileName is the input file, and outFileName is the output file.

    An example input would be:

    Code:
    70.161.31.80 - - [30/Mar/2008:23:31:21 -0500] "GET /cocoon/~cs330web/forum/show/_axle/private.gif HTTP/1.1" 302 -
    70.161.31.80 - - [30/Mar/2008:23:31:21 -0500] "GET /cocoon/~cs330web/forum/show/_axle/feed-icon16x16.png HTTP/1.1" 302 -
    70.161.31.80 - - [30/Mar/2008:23:31:21 -0500] "GET /axle/Forum/_axle/private.gif HTTP/1.1" 304 -
    70.161.31.80 - - [30/Mar/2008:23:31:21 -0500] "GET /axle/Forum/fckeditor/editor/fckeditor.html?InstanceName=text&Toolbar=ForumToolbar HTTP/1.1" 304 -
    70.161.31.80 - - [30/Mar/2008:23:31:21 -0500] "GET /axle/Forum/fckeditor/fckconfig.js HTTP/1.1" 304 -
    127.0.0.1 - - [30/Mar/2008:23:31:28 -0500] "GET / HTTP/1.0" 200 2499
    127.0.0.1 - - [30/Mar/2008:23:31:29 -0500] "GET / HTTP/1.0" 200 2499
    I need to take this input and to the output file only the information after GET and either to the end of the line or to a "?"

    Now, I currently have these 3 functions to do the stripping of the other information:


    To extract the quoted request:
    Code:
    string extractTheRequest(string logEntry)
    {
      string::size_type requestStart = logEntry.find('"');
      string::size_type requestEnd = logEntry.rfind('"');
      if (requestStart != requestEnd) 
        {
          return logEntry.substr(requestStart+1, requestEnd-requestStart-1);
        }
      else
        return "";
    }
    Check if it's a GET request:
    Code:
    bool isAGet (string request)
    {
      return request.size() > 3 && request.substr(0,4) == "GET ";
    }
    And extract the locator part:
    Code:
    string extractLocator (string request)
    {
      // strip off the GET
      string::size_type locatorStart = 3;
      
      // Skip any blanks
      while (request[locatorStart] == ' ')
        ++ locatorStart;
    
      // The locator ends at the first blank or ? after that.
      string::size_type locatorEnd = locatorStart;
      while (request[locatorEnd] != ' ' && request[locatorEnd] != '?')
        ++ locatorEnd;
    
      string locator = request.substr(locatorStart, locatorEnd-locatorStart);
      return locator;
    }
    I am currently trying to write a function that stores the locator part of the request in 1 array and then counts the times a single locator is found in a second array. (essentially parallel arrays).

    I can get the information stored in the arrays but it still has everything before the GET stored too which I don't want. Also, I can't get the counter to work either... Any help would be greatly appreciated! Thanks!

  2. #2
    Registered User
    Join Date
    Nov 2003
    Posts
    161
    I tried running the extractTheRequest() function and it seems to have returned everything in the quotes properly.

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    122
    yeah I know but I don't know how to get it from that function to my newly created function to get it in the array.

  4. #4
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Well, we don't know either until you post that code.

    I've tweaked your code. Got rid of isAGet() in the process.
    Code:
    string extractTheRequest(string logEntry)
    {
    	string temp ; 
    	string::size_type requestStart = logEntry.find("\"GET ",0 );
    	string::size_type requestEnd = logEntry.rfind('"');
    	if (requestStart != requestEnd && requestStart != string::npos) 
    	{
    		requestStart += 4 ;  // Index past '"GET '
    		temp = logEntry.substr(requestStart, requestEnd-requestStart);
    		return temp ; 
    	}
    	return "";
    }
    
    string extractLocator (string request)
    {
    	string::size_type locatorStart = 0;
      
    	// Skip any blanks
    	while (request[locatorStart] == ' ')
    		++ locatorStart;
    
    	// The locator ends for the first blank or ? after that.
    	string::size_type locatorEnd = locatorStart ;
    	while (request[locatorEnd] != ' ' && request[locatorEnd] != '?') 
    		++locatorEnd;
    
    	string locator = request.substr(locatorStart, locatorEnd-locatorStart);
    	return locator;
    }
    edit - some vars left in from debugging.
    Last edited by Dino; 09-10-2008 at 02:48 PM.
    Mainframe assembler programmer by trade. C coder when I can.

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    62
    Quote Originally Posted by Todd88 View Post
    (...)
    I am currently trying to write a function that stores the locator part of the request in 1 array and then counts the times a single locator is found in a second array. (essentially parallel arrays). (...)
    Don't do this. Use a map instead:

    Code:
    std::map<std::string, int> m;
    std::map<std::string, int>::const_iterator i;
    
    // while not eof ... read next request
    
    locator = extractLocator(request);
    m[locator]++;
    
    // end of while
    
    for (i = m.begin(); i != m.end(); ++i)
        cout << i->first << " called " << i->second << " times." << endl;

  6. #6
    Registered User
    Join Date
    Apr 2008
    Posts
    122
    Unfortunately I am forced to write a function as it is part of my requirements. I know this would be so easy if I knew how to get the string from the function "extractLocator" because that function gives me exactly what I need. I can't do this:

    Code:
    void histogram(const int MaxPages, istream& input, ostream& output)
    {
    
        string locators[MaxPages];
        int counts[MaxPages];
        string locator;
      // Step 1 - set up the data
      // Data should be stored in two parallel arrays, locators and counts.
      // locators[i] will be the i_th locator string and counts[i] will be the
      // count of how many times that particular locator has been requested.
      for(int i = 0; i < MaxPages; i++)
      {
          locators[i] = locator;
          cout << locator << endl;
      }
    
      // Step 2 - read and count the requested locators
    
      // Step 3 - write the output report
    
      // Step 4 - cleanup
    
    }
    I just cout the locator to see if it works and it doesn't.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Why wouldn't you do
    Code:
    locators[i] = extractLocator(input[something_appropriate_here]);
    ?
    (You may need to figure out how to get a line out of input, unless input is just one line of data, but I don't think it is.)

  8. #8
    Registered User
    Join Date
    Apr 2008
    Posts
    122
    You're right, input is a whole bunch of lines. And for some reason extractLocator(input[something_appropriate_here]); doesn't work because it is telling there is no match for operator[].

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Todd88 View Post
    You're right, input is a whole bunch of lines. And for some reason extractLocator(input[something_appropriate_here]); doesn't work because it is telling there is no match for operator[].
    That's because I thought you were passing in a string, rather than a istream. In that case, you read a line into a string with getline, and then call extractLocator on that string.

  10. #10
    Registered User
    Join Date
    Apr 2008
    Posts
    122
    Okay I got it to work but it is still storing everything outside the quotations.

    for(int i = 0; i < MaxPages; i++)
    {
    getline(input,locators[i]);
    cout << locators[i] << endl;
    }

  11. #11
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    And where exactly does the word "extractLocator" appear in your above code?

  12. #12
    Registered User
    Join Date
    Apr 2008
    Posts
    122
    it doesn't . I'm confused...sorry.

  13. #13
    Registered User
    Join Date
    Apr 2008
    Posts
    122
    Code:
    for(int i = 0; i < MaxPages; i++)
      {
          getline(input,locators[i]);
          extractLocator(locators[i]);
          cout << locators[i] << endl;
      }
    doesn't quite work...

  14. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Just because you wrote a function called extractLocator doesn't mean the compiler is just going to call it at various places -- you have to specify what and where and when. You want the locators[i] to be the result of the extractLocator function, so you have to call that function and assign the result into your locators array. You'll also have to have another string waiting nearby (this can be a temporary sort of thing) to hold the full line of input as it gets read in, so that you have something to apply the extractLocator function on.

  15. #15
    Registered User
    Join Date
    Apr 2008
    Posts
    122
    Okay, based on what you just told me, I sort of understood you and wrote up something.

    Code:
     for(int i = 0; i < MaxPages; i++)
      {
          getline(input,address);
          extractLocator(address) = locators[i];
          cout << locators[i] << endl;
      }
    I don't think this is quite right, is it?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sequential file program
    By needhelpbad in forum C Programming
    Replies: 80
    Last Post: 06-08-2008, 01:04 PM
  2. Can we have vector of vector?
    By ketu1 in forum C++ Programming
    Replies: 24
    Last Post: 01-03-2008, 05:02 AM
  3. help with text input
    By Alphawaves in forum C Programming
    Replies: 8
    Last Post: 04-08-2007, 04:54 PM
  4. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  5. Looping when outputting to a file
    By nizbit in forum C Programming
    Replies: 4
    Last Post: 03-05-2005, 10:26 AM