How to delete the specified line of a file in C ++ on CUI con

Source: Internet
Author: User

Introduction:
In this article, you'll learn about two points on file operation. 1. How to delete the specified line of a file. 2.How to replace the specified line of a file.
Yesterday someone asked me how to delete the specified row in the file (under the console). I think this problem is different from that in CUI in the GUI. I tried it, I think there are still a lot of things to pay attention to, so I will sort out my experiences. If you have any mistakes, please correct me.
In the GUI, when we edit text in various controls, pressing enter for another line will generate two characters "\ r \ n ", in CUI, it depends on the format when we write data. Of course, if it is in CUI, we certainly should not use "\ r \ n" as a line break when we change the line, because we can use only one '\ n', and there is no need to waste another character. Of course, the method used in this article to delete a specified row is also applicable to the string with "\ r \ n" line breaks, but this article mainly targets CUI. On the contrary, there are many restrictions on how to replace a specified row.
1. delete a specified row
Idea: two methods: one is to locate the file pointer to the beginning of the row to be deleted, calculate the length of the row, and then replace each character with a space. The other is to input a character array into the entire file, and then treat it as a string, and then locate two locations. One is to extract the first line of the line to wrap, the other is the first line of the next line, and then all the characters from the next line to the end are translated to the beginning of the line to be replaced, that is, the overwrite method, which can be easily implemented using strcpy.
Analysis: if you use the first method, the advantage is that you do not need to read the entire file (generally, you only need to read the next row of the row to be deleted, and the following code has an analysis .) In addition, you do not need to pan forward all the file content after the row to be deleted. The disadvantage is that it is not a real deletion, but to replace the content of the row to be deleted with spaces. The file size will not be reduced, which is also a fatal weakness, but if there is a need to replace a line of content, it is it. The second method is to delete the specified row, because the file content should be read into a character array and translated, so the performance is not as good as the first one, but it is actually deleted, and the second method is to treat the file content as a string, the output stream of the C ++ file does not carry the terminator '\ 0' when writing a string to the file, that is, if' \ 0' is not displayed when writing the file ', there is no '\ 0' in the file. That is to say, when we read all the characters in a file into a character array, there will be no' \ 0' in this array, after reading the file content, we have to add '\ 0' at the end so that we can use the string processing function for processing. Let's first implement the second method.
DelLine functions:
Example string: "aaaaa \ nbbbbb \ nccccc \ n"
Now, let's think about how to implement it. We still have a problem to solve, that is, how to determine the first and last position of the line to be replaced. For example, we want to delete the second line now, we must determine the two positions marked in green and then pass them to strcpy. We can use the character search function strchr (string pointer, '\ n ') find the two locations. If the two locations are found, the function returns a pointer to '\ n'. If the two locations are not found, NULL is returned. In this case, note that if we want to delete the first row, you only need to find the first '\ n. Now, I have written the delLine function. The prototype is void delLine (char * pFilepath, int nLine). The first is the file path, and the second is the row to be deleted, note: Before calling this function, you must disable all the streams that open the file. This is determined by the System File Sharing policy, because the delLine must read and write the file, if a stream that writes the file is not closed before calling this function, the delLine function will fail to open the file when writing the file, because the system does not need to allow multiple users to write the file at the same time. The following code is provided:
Void delLine (char * pFilepath, int nLine)
{
// Open file
Ifstream file (pFilepath );
Int I = 0;
// Allocate read buffer. Note: can't more than 1 MB
Char buff [1, 1024*30];
While (! File. eof () // Read whole file
Buff [I ++] = file. get ();
File. close ();
Buff [I] = '\ 0 ';
Char * pLine = buff;
Int j = 0;
// Search newline character '\ N'
While (j ++ <nLine-1 & pLine)
{
PLine = strchr (pLine + 1, '\ n ');
}
If (pLine)
{
Char * pNextLine = strchr (pLine + 1, '\ n ');
// Cover the line we want to delete.
If (pNextLine ){
If (nLine = 1)
Strcpy (pLine, pNextLine + 1 );
Else
Strcpy (pLine, pNextLine );
}
}
// We did it, write the file handled.
Ofstream out (pFilepath );
J = 0;
I = strlen (buff );
While (I --)
Out. put (buff [j ++]);
Out. close ();
}
Well, solution 1 is implemented below. The core of solution 1 is to determine the length of the line to be replaced. How can this problem be solved? Think about it. I call the getline function twice in a row. If I do not call getline once, I call tellg to get the text value of the pointer to the current file, and then subtract the previous one from the next one, in this way, we get a length. This length is not the length of the string. Let's see this string "aaaaa \ nbbbbb \ nccccc \ n". Now we need to replace the second line, in the first call, the location is 7, that is, the character location after the first '\ n', that is, the first address of the next line, the second call to getline gets the position of the first c, that is, 14. If we want to replace it, we only need to replace 5 B, apparently it should be 14-7-2 = 5, so we have to give two length differences and then subtract 2. note that the file pointer has moved to the next line when getline is called for the second time, so you must call seekg to adjust the file pointer. Replacing the first row is also a special case. You only need to call getline once to determine the length of the first row. In addition, the line string you want to replace must be greater than or equal to the length of the original line. When it is greater than the length of the original line, the excess part will be truncated. If it is less than, it cannot be completely replaced, A prompt should be given, so the new string passed during the call should not be long, we can add a lot of spaces after the valid characters, so that everything is fine. The following code is provided:
 
Void replaceLine (char * pFilepath, int nLine, char * pReplace)
{
NLine --;
Fstream file (pFilepath );
Char buff [100];
Fstream: pos_type pos, len;
Int I = 0, k = 0;
// If the first line
If (nLine = 0)
{
Pos = file. tellg ();
If (! File. eof ())
File. getline (buckets, 100 );
Len = file. tellg ()-pos; // work out the length of the line we want to delete
File. seekg (pos); // set the file pointer to the start of the line to be deleted
}
// Not first line
Else {
While (I ++ <nLine)
{
If (! File. eof ())
File. getline (buckets, 100 );
Pos = file. tellg ();
If (! File. eof ())
File. getline (buckets, 100 );
Len = file. tellg ()-pos; // work out the length of the line we want to delete
File. seekg (pos); // set the file pointer to the start of the line to be deleted
}
}

K = len;

// Note: we assume there is not '\ r 'before' \ n', it's depend on the write format of you.
If (strlen (pReplace) <K-2)
{
Printf ("Error: new line must be longer than or equal to the original line \ n ");
Return;
}
File. write (pReplace, K-2 );
File. close ();
}
Now let's test:
Replace the first line with eeeee, and the second line with f. Note that f only has one character. Therefore, we should add n spaces according to the length-not-short principle, in replaceLine, the system automatically intercepts the length of the original line, and then deletes the third line.
Void main (){
// Create a file
Ofstream out ("notestxt ");
Out <"aaaaa \ n" <"bbbbb \ n" <"ccccc \ n" <"ddddd \ n ";
Out. close ();
// Replace the first line
Char * pReplace = "eeeeeeeeeeeeeee ";
ReplaceLine ("notestxt", 1, pReplace );
PReplace = "f ";
ReplaceLine ("notestxt", 2, pReplace );
DelLine ("notestxt", 3 );
Ifstream in ("notestxt ");
Cout <in. rdbuf ();
}
The output result is:
Eeeee
F
Ddddd

 


Excerpted from building a high-end server without sand float
 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.