C++/fseek()

Advertisement


Question
I can't understand what msdn says about fseek(). How would i use it to move a file pointer from the 20th letter to the 45th letter and vice versa in a file like "c:\temp.txt"?

Answer
First a few points.

I do not know if you intended it but you are asking this of a C++ expert not a C expert. I mention this as fseek forms part of the standard C library file operations. Of course the C++ standard library inherits these functions, but they are not directly compatible with C++ IOStreams. You therefore have to have opened the file using the C fopen function, and close it using the C fclose function.

Next, you have to be careful when using fseek with text files. Things like end of line character sequences and the size of characters used can make a difference to the position values you need to pass to fseek via its offset parameter. The fseek function positions to the requested byte position within the referenced file, it knows and cares nothing about characters or their encoding making up the data of the file.

You also have all that silliness to do with character 26 (ctrl-Z) being interpreted as end of file in text mode - a Microsoft hangover from the days of MS-DOS. Then there is the effect caused by skipping over the byte order mark (if there is one), which as far as I know has to do with text files of characters in various Unicode encodings (so hopefully can be ignored in simple cases). See http://unicode.org/unicode/faq/utf_bom.html#BOM for more information on byte order marks.

You ask about positioning to the letter positions. Not all characters are letters and not all characters are printable. As I said fseek knows and cares nothing about the data or meaning of the values in a file and therefore cannot tell a letter from any other character type.

So assuming you meant characters when you mention letters in your question and assuming characters are all the same size and are byte sized then to position to the 45th character when starting with the file pointer positioned at the 20th character you can do the following:

   status = fseek( file, 44L, SEEK_SET );

The fseek call shown above assumes file is a FILE * pointing to a valid open FILE structure. 44L specifies the position as a long integer constant, SEEK_SET is a value indicating that 44L is used to specify the position counting from the beginning of the file. As the beginning of the file is at position 0 and not position 1 we have to subtract 1 from the byte number we want if we count the first character as character 1.

The status variable is an int and is used to hold the returned value which is 0 on success and some non-zero value if fseek failed. If fseek fails you should check errno for more details or call a function such as perror as in the MSDN example, which converts the errno value to a string, prefixes the passed text and displays it on stderr (as associated with std::cerr in C++).

Alternatively you could specify the position to move to relative to the current position which would be the value given by the difference between the new position from the current position, thus 45-20 = 25:

   status = fseek( file, 25L, SEEK_CUR );

Here the way the position value is interpreted is specified as SEEK_CUR, meaning to count from the current file position. This assumes of course that the file pointer position is in fact at position 19 (i.e. the 20th byte counting from 0) to start with. If it were at (say) position 112 then it would end up at position 137.

The reverse would be either:

   status = fseek( file, 19L, SEEK_SET );

That is move to position 20 as counted from 0, the beginning of the file.

Or:
   status = fseek( file, -25L, SEEK_CUR );

Which means move to the current position less 25, which assuming the file pointer is positioned at position 44 (i.e. byte 45 counted from 0) to start with would position it to position (44-25) = 19 (i.e. byte 20 counted from 0).

If you look carefully at the signature for fseek then you would notice that the offset parameter is specified as a long value - that is it is a signed value and so can be negative.

I should note that we could also position relative to the end of the file by specifying SEEK_END as the third parameter value. However this would mean we would need to know how long the file was in bytes so we can calculate the distance from the end of the file to the positions we require and so seems to be more effort than it is worth in this case.

Hope this helps. If you require further information then please ask another question.  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.