Thread: File I/O

  1. #1
    Registered User
    Join Date
    Sep 2006
    Posts
    55

    File I/O

    I am trying to remove lines that start with/contain only integers.

    So for example this input file:

    15
    Humpty Dumpty
    12
    sat on a
    5
    wall

    Should be ouput to a file like so:

    Humpty Dumpty
    sat on a
    wall

    I have tried the following:

    Code:
     string line;
     while (INFILE)
     {
      getline(INFILE, line) ;
      
      if(line[0] == '0' || '1' || '2' || '3' || '4' || '5' || '6' || '7' || '8' || '9')
      {
       line.clear() ;
      }
    Basically what I am trying to achieve is to read a line from an input file. If that line starts with integers, remove it somehow and continue to the next line. If a line does not have any integers in it, output it to the output file. I have tried doing this with a for loop to go through the entire string, but it did not work as I thought it would. Anyway, I am stuck and would greatly appreciate any help. Thanks.

  2. #2
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    The following code will cause it to jump immediately to the start of the while loop if the first character of the line is a number.
    Code:
    #include <cctype>
    
    ...
    if(isdigit(line[0]))
    {
       continue;
    }
    ...
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    55
    Thanks! That did it.

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    55
    I am now trying to extract the words from the string and was wondering if getline inserts a special character at the end of the line it reads from the input file? Because I need to compare two lines at a time from the file and also count the words.

    My original thought was to search through line, and output everything to another string up until a '\n' or '\0'. But I can't get it to work.

    My other thought was to copy the contents of line to prev_string and then continue with the next line and copy line to next_line. Any suggestions? Thanks.
    Code:
     string line, prev_line, next_line ;
     while (INFILE)
     {
      getline(INFILE, line) ;
      
      if(isdigit(line[0])) 
      {
      continue ;
      }

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Maybe you answered this question in a lost thread, but why don't take advantage of the fact that you know every other line will be a number?

    Was it you who had:
    Code:
    while (getline(INFILE, line))
    {
      getline(INFILE, line);
    I told somebody (maybe you) not to do that, but in this case I think it is best because it ignores the line with the number.


    >> was wondering if getline inserts a special character at the end of the line
    Nope. The last character will be 'y' in the Humpty Dumpty line. The call to getline removes the '\n' (newline) character that normally ends a line.

    >> But I can't get it to work.
    What did you try? Just outputting the line string should work fine.

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    55
    Was it you who had:
    Code:
    while (getline(INFILE, line))
    {
    getline(INFILE, line);I told somebody (maybe you) not to do that, but in this case I think it is best because it ignores the line with the number.
    Yes, that was me. It seems that many past threads were lost.


    So everything else is working now, except one small problem that I can't fix.

    Code:
     string line, prev_line, next_line ;
     while (INFILE)
     {
      while( getline(INFILE, line) )
      {
       if(isdigit(line[0])) 
       {
        continue ;
        prev_line = line ;
       } 
       
      next_line = line ; 
      
      OUTFILE << prev_line << endl << next_line ;
    In the following block, a new line is being inserted into the string because when I execute the code, I get one blank line at the top of the file, but from there on, every thing else is fine. I tracked down the cause to this block, but have not been able to fix it.

    Code:
    if(isdigit(line[0])) 
       {
        continue ;
        prev_line = line ;   }
    Last edited by Bnchs; 03-23-2007 at 03:34 PM.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    The prev_line = line ; code will never be executed, it comes after the continue.

    There shouldn't be any extra blank lines. Can you provide more code? Is your input file exactly as you posted above? I don't think there is any need for prev_line or next_line, what are you using those for?

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    55
    I am using the prev and next lines to do the manipulations defined by the functions.

    The input file is exactly in the same format as I posted before. So I end up getting an output file with:

    // blank line here ///
    Humpty Dumpty
    sat on a
    wall


    Code:
    #include <iostream>
    #include <string>
    #include <cctype>
    #include <fstream>
    
    using namespace std;
    
    
    string make_upcase(string &s) ;
    
    int count_words(string s) ;
    
    bool are_anagrams(string s, string s2) ;
    
    
    int main()
    {
     cout <<"Enter the output filename: " ;
     cin >> output_filename ;
     OUTFILE.open(output_filename.c_str()) ;    
     
     string line, prev_line, next_line ;
     while (INFILE)
     {
      while( getline(INFILE, line) )
      {
       if(isdigit(line[0])) 
       {
        continue ;
        prev_line = line ;
       } 
       
      next_line = line ; 
      
      OUTFILE << prev_line << endl << next_line ;
        
      }// End of while( getline(INFILE, line) ) loop
     
     } // End of while(INDATA) loop
    
    
     system("Pause");
     return 0;
    
    }// End main
    
    
    string make_upcase(string &s) 
    //----------------------------------------------------------------------------
    //Creates a new string that is an upper case version of the original string. 
    //Pre-Condition: Original string is lowercase.
    //Post-Condition: New String is all Caps.
    //----------------------------------------------------------------------------
    
    {
     string uppercase_string ;
     if(! s.empty()) //Does the following if the string is not empty
     {
     
      string letter ;
      for(int i = 0; i < s.length(); i++)
      {
       letter = toupper(s[i]) ; //coverts single character to uppercase
                               //using <cctype> header
       uppercase_string.insert(i,letter) ;
      } 
       cout <<uppercase_string <<"\n"; 
        
     }                  
        return uppercase_string ;  
    }
    
    
    //***NOT FINISHED YET
    int count_words(string s)  //determines how many words are in the string. 
    {
     return s.length() ;  
    }	
    
     
    bool are_anagrams(string s, string s2)
    //----------------------------------------------------------------------------
    //Determines whether the strings are anagrams of one another.
    //Pre-Condition: Two strings are passed to the function, original string and 
    //               uppercase string.
    //Post-Condition: If the two strings are anagrams of eachother, the function 
    //                returns true, else it returns false.
    //----------------------------------------------------------------------------
    {
     if(s.length() != s2.length())
     {
      return false ;
     }
     
     if(!s.empty())
     {
      for(int i = 0; i < s.length(); i++)
      {
       for(int j = 0; j <s2.length(); j++)
       {
        if(s[i] == s2[j])
        {
         return true ;
        }
        else
        {
         return false ;
        }
       } //end of int j for loop 
      } //end of int i for loop
     } //end if  
    
    } //end of function definition
    Last edited by Bnchs; 03-23-2007 at 03:55 PM.

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> I am using the prev and next lines to do the manipulations defined by the functions.
    You mean you will be using them later on? Because you aren't using them now. That is why you get the blank line. You output prev_line which is always empty (you never set prev_line to any value). Then you output a newline (with endl), then you output next_line which always equals the current line.

    Don't output prev_line and put the endl after next_line and you will have it the way you want it.

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    55
    But then how can I get the next line from the file at that moment? Because I am trying to get a string with the current line and a string with the next line to do comparisons on them.
    Last edited by Bnchs; 03-25-2007 at 08:49 AM.

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> I am trying to get a string with the current line and a string with the next line to do comparisons on them.

    Ok, then you will need to use two variables like prev_line and line. However, you have to do special case processing to handle the first time through when prev_line will be empty. You also have to set prev_line correctly. The way you set next_line looks like a better choice than the prev_line code above.

    To handle the first time through, if you know these lines will never be empty, then just check the prev_line string to see if it is empty and skip the comparison if it is.

    For output, are you trying to output both the prev_line and the current line at the same time meaning each line will appear twice? If so, then output both. If not, then only output line. It's that simple.

  12. #12
    Registered User
    Join Date
    Sep 2006
    Posts
    55
    At this point, everything is working except the logic for my are_anagrams() function.

    The algorithm I am trying to implement is:
    first to check if the strings are equal in size. If not, then they can't be anagrams and return false. Next, go through both strings and check if every character in the first string is in the second string. If so, they are anagrams, else, they are not.

    I think that checking if s[i] == s[j] is the problem and am stuck here.

    Code:
    bool are_anagrams(string s, string s2)
    //----------------------------------------------------------------------------
    //Determines whether the strings are anagrams of one another.
    //Pre-Condition: Two strings are passed to the function, original string and 
    //               uppercase string.
    //Post-Condition: If the two strings are anagrams of eachother, the function 
    //                returns true, else it returns false.
    //----------------------------------------------------------------------------
    {
     if(s.length() != s2.length())
     {
      return false ;
     }
     
     if(!s.empty())
     {
      for(int i = 0; i < s.length(); i++)
      {
       for(int j = 0; j <s2.length(); j++)
       {
        if(s[i] == s2[j])
        {
         return true ;
        }
        else
        {
         return false ;
        }
       } //end of int j for loop 
      } //end of int i for loop
     } //end if  
    
    } //end of function definition

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    An anagram just means that all the letters are the same, they are just in different orders (like "hello world" and "her owl doll") right?

    One problem you have is that you return true if s[i] == s2[j]. But that is going to happen a lot and you don't want to return true right away. Similarly, you return false if s[i] != s2[j] which again wil happen a lot. In your current code you only ever compare s[0] and s2[0] and return true or false based on that comparison.

    However, there is a problem with your current idea. You might match "thehen" with "then" because you don't account for how many times a letter occurs. You need to remove the letter from both strings if you find a match before continuing on.

    Another idea is to sort the strings' characters and then just compare the strings.

  14. #14
    Registered User
    Join Date
    Sep 2006
    Posts
    55
    Going with what you suggested, I sorted the strings and then used compare(). If compare() returns zero, then they are anagrams, else, they are not, and its working and I have a working program. Thanks for your help Daved, and XSquared.

  15. #15
    Registered User
    Join Date
    Sep 2006
    Posts
    55
    Unfortunately, I just discovered a runtime bug, where I am getting results that two strings are not anagrams because one has whitespace in it. By any chance is there some function that can strip whitespace from a string?

    Or, since a 'space' has a lower ASCII value than letters (it would be a matter of simply removing the first index from the string), a way to find whitespace inside a string ?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Data Structure Eror
    By prominababy in forum C Programming
    Replies: 3
    Last Post: 01-06-2009, 09:35 AM
  2. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  3. 2 questions surrounding an I/O file
    By Guti14 in forum C Programming
    Replies: 2
    Last Post: 08-30-2004, 11:21 PM
  4. File I/O problems!!! Help!!!
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 05-17-2002, 08:09 PM
  5. advice on file i/o
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 11-29-2001, 05:56 AM