File input / output in C (3)
Original: Ilia Yordanov, Loobian@cpp-home.com
Master input / output flow
In this chapter, I will mention some useful functions. I will demonstrate how to open a file that can be read and written at the same time; in addition, I will introduce you to other ways to open the file, and how to determine whether the open operation is successful. Therefore, please read down! So far, I have been only a single open file for you: either open for reading, or open for writing. But files can also be opened in other ways. To date, you should have known the following method: ifstream OpenFile ("cpp-home.txt");
Oh, this is not the only way! As mentioned earlier, the above code creates a class IFStream object and passes the name of the file to its constructor. However, in fact, there are many heavy-duty constructors that accept more than one parameters. At the same time, there is an Open () function to do the same thing. Here is an example of more than one code, but it uses an Open () function: ifstream openfile;
OpenFile.open ("cpp-home.txt");
You will ask: What is the difference between them? Oh, I have done a lot of tests, the conclusion is different! Just if you want to create a file handle but don't want to specify a file name immediately, you can use the open () function to be specified. By the way, an example of using an Open () function is given: If you open a file, then turn it off, it is intended to open another file with the same file handle, so that you will need to use the open () function. Consider the following code example:
#include
Void Read (ifstream & t) // Pass the file stream to the function
{
// the method to read a file, That i showed you before
CHAR CH;
While (! t.eof ())
{
T.Get (CH);
Cout << CH;
}
COUT << Endl << "--------" << endl;
}
void main ()
{
IFStream T ("file1.txt");
Read (T);
T.close ();
T.Open ("File2.txt");
Read (T);
T.close ();
}
According to this, as long as file1.txt and file2.txt are stored and stored, you will see it. Now, the file name is not the only parameter you only pass to the Open () function or constructor (actually the same). Here is a function prototype: ifstream OpenFile (Char * filename, INT OPEN_MODE);
You should know that FileName represents the name of the file (a string), and the new appearance is Open_Mode. Open_MODE value is used to open the file in what way. Here is a list of open modes:
name
description
ios :: in
Open a readable file
iOS :: OUT
Open a writable file
ios :: app
All the data you write will be appended to the end of the file, this way you use ios :: OUT
ios :: ATE
All the data you write will be appended to the end of the file, this way does not use ios :: OUT
ios :: Trunk
Delete the file originally existing content (empty file)
ios :: nocreate
If the file to be opened does not exist, call the open () function in this parameter will not be possible.
ios :: Noreplace
If the file to be opened already exists, you try to open an error when you open with the open () function.
ios :: binary
Open a file in binary form.
In fact, the above values belong to an enumerated type INT constant. But in order to make your programming career is too painful, you can use those names like you see it. Here is an example of how to use open mode: #include
void main ()
{
OFSTREAM Savefile ("File1.txt", iOS :: ATE);
Savefile << "That's new! / N";
Savefile.close ();
}
As you can see in the table: Use ios :: ATE will start writing from the end of the file. If I don't use it, the original file content will be overwritten. However, since I have already used it, then I will only add it at the end of the original file. So, if file1.txt original content is this: hi! This is test from www.cpp-home.com!
So after executing the above code, the program will add "That's New!", So it looks like this: hi! This is test from www.cpp-home.com! That's New!
If you plan to set up more than one open mode flag, you only need to use or operate or |, like this: ios :: Ate | ios :: binary
I hope now you have understood what "Open Mode" means! Now, it is time to show you some truly useful things! I have to bet you still don't know how to open a file that can be read and written simultaneously! The following is the implementation method: fstream file ("cpp-home.txt", ios :: in | os :: out);
In fact, this is just a statement statement. I will give you a code example after the following rows. But at this time, I first want to mention some content you should know. The above code creates a handle of a stream file called "file". As you know, it is an object of the FStream class. When using FSTREAM, you should specify ios :: in and iOS :: OUT as the open mode of the file. This way, you can read the files at the same time, and you don't have to create a new file handle. Oh, of course, you can only read or write operations. That way, you should use only iOS :: in or only iOS :: OUT - To think about: If you plan to do this, why don't you use IFStream and OFSTREAM to be implemented? Let's give the sample code first:
#include
Void main () {
FStream File ("Test.txt", ios :: in | os :: out);
File << "hi!"; // Write "Hi!" Into the file
Static Char Str [10]; // When using STATIC, the array will automatically initialize // is cleared to zero
File.seekg (iOS :: beg); // Back to the file header // This function will explain the file >> str; cout << str; endl;
File.Close ();
OK, there are some new things here, so I will explain their progressive:
FStream File ("Test.txt", iOS :: in | iOS :: out); - This line creates a FSTREAM object, which will open the Test.txt file when executed. This means you can read the files at the same time and write data.
File << "hi!"; - I bet you already know what it means.
Static char str [10]; - This will create a character array of capacity 10. I guess static or some strangers for you, if this is ignored it. This is only initialized while creating an array.
File.seekg (ios :: beg); - OK, I want you to understand what it will do, so I will start with some a bit of the problem, but quite important content starts my explanation. Remember it? While (! OpenFile.eof ())
{
OpenFile.get (CH);
Cout << CH;
}
Are you very much looking to know what operations do you really do behind? Whether it is or not, I will explain it for you. This is a WHILE type loop, which will continue until the program's operation reaches the end of the file. But how does this loop know if it has arrived at the end of the file? Well, when you read the file, there will be something similar to "Inside-Pointer", which indicates that you read (written) which position has arrived, just like notepad cursor. And whenever you call OpenFile.Get (CH), it returns the character of the current location, stored in a CH variable and moves this built-in pointer forward. So the next function is called again, it will return next character. This process will continue to repeat until the end of the file is read. So let's go back to the code: function seekg () will position the built-in pointer to the specified location (determined by you). you can use:
iOS :: beg - Move it to the first end of the file
iOS :: End - Move it to the end of the file
Alternatively, you can set the number of characters that jump forward or backward. For example, if you want to position 5 characters positioned to the current location, you should write:
File.seekg (-5);
If you want to skip 40 characters, you should write:
File.seekg (40);
At the same time, I must point out that the function seekg () is overloaded, and it can also bring two parameters. Another version is like this:
File.seekg (-5, iOS :: end);
In this example, you will be able to read the last 4 characters of the file text because:
1) You reach the end (ios :: end)
2) You then reached the position of the top five characters at the end (-5)
Why do you read 4 characters instead of 5? Hey, I only have to think that the last one is "throwing", because the end of the file is neither a character is not a blank character, that is just a location (the translation: maybe iOS :: End "finger" Being out of the scope of the file itself, it is specifically that it is a next position to the last character of the file. It is a bit similar to the END iteration point of each container in STL to point to the next position of the last element. This design may be easy to circulate Traversing in traversal). You may want to know why I want to use this function. Hey, when I wrote "Hi" into the document, the built-in pointer will be set to it later ... which is the end of the file. So I must set the built-in pointer to the file start. This is the exact use of this function here.
File >> Str; - This is also fresh! Oh, I am sure that this line of code lets you think of CIN >>. In fact, there is a considerable relationship between them. This line will read a word from the file and store it in the specified array variable.
For example, if there is such text pieces in the file:
Hi! Do you know me?
With File >> STR, you will only output "Hi!" To the STR array. You should have already noticed that it is actually read the space as a separator of the word.
Since I have only a single "hi!" In the file, I don't need to write a while loop, which will take more time to write the code. This is why I use this method. By the way, until now, in the While loop of the read file I use, the way the program read file is read by a character. However, you can also read a word in a word, like this:
Char Str [30]; / / / / The length of each word cannot exceed 30 characters
While (! OpenFile.eof ())
{
Openfile >> Str;
Cout << Str;
}
You can also read it in a line, like this:
Char line [100]; // Each whole line will be stored here while (! openfile.eof ()) {
OpenFile.getLine (Line, 100); // 100 is the size of the array
Cout << line << endl;}
You may now want to know which method should be used. Well, I suggest you use the way you read by line or read the way I mentioned. The way to read by words is not a good solution, because it does not read the new line of information, so if you have a new line in your file, it will not display the contents of the content, Instead, add the text that has been printed. And use getLine () or get () will show you the original face!
Now, I will tell you how to detect whether the file is open. Really, a good method is small, I will involve them. It should be noted that when "X" appears, it can actually replace "O", "i", or you can nothing (that will be a FSTREAM object).
Example 1: The most common practice
Xfstream File ("cpp-home.txt");
IF (! file) {
Cout << "Error Opening The File! Aborting ... / n";
Exit (1);
Example 2: If the file has been created, return an error
OFSTREAM File ("Unexisting.txt", iOS :: nocreate;
IF (! file)
{
Cout << "Error Opening the file! Aborting ... / n"; exit (1);
}
Example 3: Using a FAIL () function
OFSTREAM File ("Filer.txt", ios :: nocreate;
IF (file.fail ())
{
Cout << "Error Opening The File! Aborting ... / n";
Exit (1);
}
The new thing in Example 3 is a FAIL () function. If there is any input / output error (not at the end of the file), it will return a non-zero value.
I also have to talk about some content I think it is very important! For example, if you have created a stream file object, you didn't open the file operation, like this:
Ifstream file; // can also be an OFStream
This way, we have a file handle, but we still have not opened the file. If you plan to open it later, you can use the open () function to implement it, I have already introduced it in this tutorial. But if you are in your program, you may need to know if the current handle is associated with an open file, then you can use is_open () to detect. If the file is not open, it will return 0 (false); if the file has been opened, it will return 1 (true). E.g:
OFSTREAM FILE1;
File1.Open ("file1.txt");
Cout << file1.is_open () << endl;
The above code will return 1 (the translation: refers to the file1.is_open () function, the following sentence is the same), because we have opened a file (in the second line). The following code will return 0, which is because we didn't open the file, but only created a streaming handle:
OFSTREAM FILE1;
Cout << file1.is_open () << endl;
Ok, this chapter is enough.