Thread: seekp(), seekg()

  1. #1
    Registered User Dual-Catfish's Avatar
    Join Date
    Sep 2001
    Posts
    802

    seekp(), seekg()

    I'm using both of these functions (seekp and seekg) for my ifstream and ofstream objects, but no matter what I try I'm still printing to the first line.

    What my program does is open an html file, read in a line, convert all tags to uppercase or lowercase, then output the line back into the file. All this works fine for the first line.. but my seekp, seekg functions aren't working right, and it keeps reading and outputting to the same line. How can I make it in sync with my currentLine variable? Consider the following code:

    Code:
    void CHTMLConvertDlg::OnConvert() 
    {
    	UpdateData(TRUE);
    	ifstream fin;
    	ofstream fout;
    
    	long int currentLine = 0;
    
    	fin.open(m_sFileName, ios::nocreate);
    
    	if (fin.fail())
    	{
    		AfxMessageBox("Failed to open file!");
    	} else {
    		do 
    		{
    			char line[255];
    			if (fin.is_open())
    			{
    				fin.seekg(currentLine);
    				fin.getline(line, 255, '\n');
    				currentLine++;
    			} else {
    				
    				fin.open(m_sFileName, ios::nocreate);
    				fin.seekg(currentLine);
    				fin.getline(line, 255, '\n');
    				currentLine++;
    			}
    
    			CString entireLine = line;
    			CString subLine;
    			signed int tempOffset[2] = {0,0};
    			signed int tagOffset[2] = {0,0};
    			
    			while (1)
    			{
    				
    				subLine.Empty();
    				
    
    				tempOffset[0] = entireLine.Find('<',tagOffset[0]);
    				tempOffset[1] = entireLine.Find('>',tagOffset[1]);
    
    				
    				
    				tagOffset[0] = tempOffset[0];
    				tagOffset[1] = tempOffset[1];
    
    				if (tagOffset[0] == -1)
    				{
    					break;
    				}
    
    				for (int i = 1; i < ((tagOffset[1]) - (tagOffset[0])); i++)
    				{
    					subLine = subLine + entireLine.GetAt(tagOffset[0] + i);
    				}
    				//AfxMessageBox(subLine);
    
    				if (m_bCase)
    				{
    					subLine.MakeUpper();
    				} else {
    					subLine.MakeLower();
    				}
    				
    				for (i = 0; i < subLine.GetLength(); i++)
    				{
    					entireLine.SetAt((tagOffset[0] + 1 + i), subLine.GetAt(i));
    				}
    			
    				tagOffset[0] = (tagOffset[1] - 1);
    				tagOffset[1]++;
    
    			}
    			fin.close();
    
    			fout.open(m_sFileName, ios::ate);
    
    			fout.seekp(currentLine);
    			fout.write(entireLine, entireLine.GetLength());
    			fout.close();
    		} while (!fin.eof());
    	}
    
    	fin.close();
    
    }
    Last edited by Dual-Catfish; 03-28-2002 at 11:10 PM.

  2. #2
    Registered User
    Join Date
    Aug 2001
    Posts
    52
    Recommend using different line counters for fin and fout, otherwise it seems you will be off by 1.

    After your while(1) you fin.close(). Then your do while tests for EOF. If you close the file is !EOF a valid test? Also when you reopen the fin the stream pointer is set to the beginning of the stream. Then you seekg(currentline). Seekg takes a long int arg to represent the number of bytes to seek in. You expect to seek in 1 line but you are only getting 1 byte.

    Recommend you recalculate the number of bytes you need to seek in and use that. Seekg is used for fixed structure files.

    Recommend you find a better control condition than while(1). While(1) can be a source of error.

    hth,

  3. #3
    Registered User Dual-Catfish's Avatar
    Join Date
    Sep 2001
    Posts
    802
    Hmmm, I see what you mean.
    I'm grabbing stuff from the right lines, but I'm only seeking in on byte and printing. I guess that explains why my file was getting filled with '<'s

    Is there anything besides seekg that will seek to a specified line?

    Also, I don't see anything wrong with while (1) as I have a break condition.

  4. #4
    Registered User
    Join Date
    Aug 2001
    Posts
    52
    Seekg and seekp will do it for you. However, if you are processing the file sequentialy, why use them? Just don't close the files until you are done with them and the stream pointers will naturaly track along. You'll always be at the right position. Otherwise you will need to count the bytes in each line after you have read them in, or use getc() with a charCntr variable, and count the bytes as you read the file in one char at a time.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. File copying using get() and seekg()
    By tonycorruption in forum C++ Programming
    Replies: 2
    Last Post: 01-15-2006, 01:05 PM
  2. seekp and binary files
    By simonc2 in forum C++ Programming
    Replies: 1
    Last Post: 01-19-2005, 12:30 PM
  3. Read only one line using seekg
    By RedZippo in forum C++ Programming
    Replies: 3
    Last Post: 03-31-2004, 11:10 PM
  4. Not sure if I should be using seekg()
    By manofsteel972 in forum C++ Programming
    Replies: 3
    Last Post: 03-12-2004, 08:39 PM
  5. seekg woos
    By Mario in forum C++ Programming
    Replies: 3
    Last Post: 05-26-2002, 08:51 PM