Examples of working with text files. Modification of files. Sort data in files. Convert file data to list
This topic provides examples of solutions to known problems that arise when processing text files in C++. Having worked out solutions to these problems, you will learn how to process arrays of string data, manage memory allocation, and use C++ tools to work with text files.
Contents
- 1. How to determine if the data in a text file has run out?
- 2. Function CountLinesInFile(). Count the number of lines in a text file
- 3. The GetStringsFromFileC() function. Get an array (list) of char* strings from a text file
- 4. The GetStringsFromFileS() function. Get an array of strings of type string from a text file
- 5. Function SetStringsToFileS(). Write an array (list) of strings of type string to a text file
- 6. Function ChangeStringInFileC(). Replacing a string in a text file
- 7. Function RemoveStringFromFileByIndex(). Delete a line from a file by its number
- 8. Function InsertStringToFile(). Insert a line at a given position in a file
- 9. Function SwapStringsInFile(). Swap two lines in a file
- 10. Function ReverseStringsInFile(). Reversing file lines (rearranging file lines in reverse order)
- 11. Function SortStringsInFile(). Sort lines in a file
- Related topics
Search other websites:
1. How to determine if the data in a text file has run out?
To determine the end of the file, use the eof() function. The function returns a result of type bool. The prototype of the function is as follows
bool std::eof();
here std – namespace in which the eof() function is declared.
If, when calling the function, the current read pointer points to the end of the file, then the function returns true. Otherwise, the function returns false.
Example 1. Below is a snippet of code that uses the eof() function to determine whether the end of the file is reached, which corresponds to the instance named inputFile
if (inputFile.eof() == false) { cout << "End of file not reached."; } else { cout << "End of file is reached."; }
Example 2. Most often, the eof() function is used in a while loop when reading lines in a file.
while (!inputFile.eof()) // until the end of the file { // Reading lines from a file // ... }
As soon as the end of the inputFile is reached, the loop will exit.
⇑
2. Function CountLinesInFile(). Count the number of lines in a text file
The CountLinesInFile() function returns the number of lines in a text file.
#include <iostream> using namespace std; // <fstream> module is necessary for working with files #include <fstream> // A function that determines the number of lines in a file. // The file name is set by the input parameter int CountLinesInFile(char* filename) { // 1. Declare an instance of F that is associated with the file filename. // The file is opened for reading in text format. ifstream F(filename, ios::in); // 2. Checking if a file exists if (!F) { return -1; } // 3. Calculate the number of lines in a file // 3.1. Declare additional variables int count = 0; char buffer[1000]; // buffer for saving one line // 3.2. The lines reading cycle. // Each line of the file is read by the getline () function. // Checking the end of the file is done by the eof () function. while (!F.eof()) { // Increase row counter count++; // Read one line to the buffer F.getline(buffer, 1000); } // 4. Close the file F F.close(); // 5. Return the result return count; } void main() { // Determining the number of lines in the file "TextFile1.txt" int nLines = CountLinesInFile((char*)"TextFile1.txt"); // Display the result if (nLines == -1) cout << "Error opening file"; else cout << "nLines = " << nLines << endl; }
⇑
3. The GetStringsFromFileC() function. Get an array (list) of char* strings from a text file
The list of lines can be returned in one of two ways in which one line is perceived differently:
- as a char* type. In this case, the list of strings is of type char**;
- as a type string – a list of strings is of type string*.
To determine the number of lines in a file, the function calls the CountLinesInFile() function, which is described in step 2.
#include <iostream> using namespace std; // the <fstream> module is necessary for working with files #include <fstream> // A function that returns lines of a file as a list of type char**. // Parameters: // - filename - the name of file; // - _lines - list of lines of a file of type (char**). // The function returns the total number of lines read in the file, // if the reading failed, the function returns -1. int GetStringsFromFileC(string filename, char*** _lines = nullptr) { // 1. Additional variables char** lines; int n = CountLinesInFile(filename); // get the number of lines in a file // 2. Check if row count is known if (n == -1) return -1; // 3. Declare a file variable ifstream F(filename); // open file for reading // 4. Checking if a file opened if (!F) return -1; // 5. An attempt to allocate memory for n lines try { lines = new char* [n]; } catch (bad_alloc e) { // if memory cannot be allocated, then exit cout << e.what() << endl; // display error message F.close(); // close the file return -1; } // 6. The cycle of reading strings and allocating memory for them int len; // single line length char buffer[1000]; // memory where one line from the file is written for (int i = 0; i < n; i++) { // 6.1. Read line from file F.getline(buffer, 1000); // 6.2. Determine the length of the read line for (len = 0; buffer[len] != '\0'; len++); // 6.3. Allocate memory for len+1 characters lines[i] = new char[len + 1]; // 6.4. Copy data from buffer to lines[i] for (int j = 0; j < len; j++) lines[i][j] = buffer[j]; lines[i][len] = '\0'; // add a newline character } // 7. Close the file F.close(); // 8. Write the result *_lines = lines; return n; }
Using the GetStringsFromFileC() function can be, for example, the following:
void main() { // Output the lines of the file on the screen // 1. Declare an internal variables int count; // number of lines char** lines = nullptr; // a list of strings of type char* // 2. Get a list of strings of type char** count = GetStringsFromFileC("TextFile1.txt", &lines); // 3. Check if the list is received if (count < 0) { cout << "Error" << endl; return; } // 3. Display a list of string on the screen. for (int i = 0; i < count; i++) { cout << lines[i] << endl; } // 4. Release the memory allocated for each string if (lines!=nullptr) for (int i = 0; i < count; i++) delete lines[i]; // 5. Release the memory allocated for lines if (lines != nullptr) delete[] lines; }
⇑
4. The GetStringsFromFileS() function. Get an array of strings of type string from a text file
Working with the string type is more convenient than with the char* type. The following code fragment implements the GetStringsFromFileS() function, which reads lines from a text file and writes them to an array (list) of type string. This function uses the CountLinesInFile() function, which is described in paragraph 2 of this topic.
#include <iostream> using namespace std; // the <fstream> module is necessary for working with files #include <fstream> // A function that receives a file string as an array of type string * // Parameters: // - filename - the name of file; // - _lines - array of lines of a file of type string *. // The function returns the total number of lines read. int GetStringsFromFileS(string filename, string** _lines) { // 1. Additional variables string* lines; // temporary array of strings int n = CountLinesInFile(filename); // Get a number of lines in file // 2. Checking if lines from file are read correctly if (n == -1) return -1; // 3. Declare a file variable and open the filename for reading ifstream F(filename); // 4. Checking if a file is open if (!F) return -1; // 5. Attempting to allocate memory for n strings of type string try { lines = new string[n]; } catch (bad_alloc e) { cout << e.what() << endl; // display error message F.close(); return -2; // return with code -2 } // 6. Reading lines from a file and writing lines to the lines list char buffer[1000]; // buffer for reading a line for (int i = 0; i < n; i++) { // 6.1. Read a line from a file into the buffer F.getline(buffer, 1000); // 6.2. Calculate read string length int len; for (len = 0; buffer[len] != '\0'; len++); // 6.3. Copy buffer => lines[i], use the assign() method. // Copy len bytes from buffer to lines[i]. lines[i].assign(buffer, len); } // 7. Close the file F.close(); // 8. Return the result *_lines = lines; return n; }
Using GetStringsFromFileS() function can be, for example, as follows
void main() { // Displaying an array of file lines on the screen // 1. Declare internal variables int count; // the number of lines string* lines = nullptr; // array of strings // 2. Get a list of strings of type string* count = GetStringsFromFileS("TextFile1.txt", &lines); // 3. Check if the array is received if (count < 0) { cout << "Error" << endl; return; } // 3. Display a list of lines on the screen. for (int i = 0; i < count; i++) { cout << lines[i] << endl; } // 4. Free memory allocated for lines array if (lines != nullptr) delete[] lines; }
The result of the program (the contents of the TextFile1.txt file):
#include <iostream> using namespace std; void main() { cout << "Hello world!"; }
⇑
5. Function SetStringsToFileS(). Write an array (list) of strings of type string to a text file
When working with text files, the SaveStringsToFileS() function is useful, which writes an array of strings to a file. In the following examples, this function will be used to write the modified list to a file.
#include <iostream> using namespace std; // the <fstream> module is necessary for working with files #include <fstream> // A function that writes an array of strings of type string to a text file. // Parameters: // - filename - the name of file; // - lines - an array of strings that are written to the file; // - count - number of strings. // The function returns true if the strings were saved successful. bool SetStringsToFileS(string filename, string* lines, int count) { // 1. Declare an additional variables ofstream F(filename); // Open file for writing // 2. Check whether the file was opened successfully if (!F) return false; // 3. Writing lines to a file except the last line for (int i = 0; i < count - 1; i++) F << lines[i] << endl; // 4. Write the last line as is (without the character '\n') F << lines[count - 1]; // 5. Close the file F.close(); // 6. Return the result return true; }
The following is an example of using the SetStringsToFileS() function.
void main() { // Writing an array of strings to a file // 1. Declare the internal variables int count; // number of strings string* lines = nullptr; // array of strings // 2. Form the strings try { // attempt to allocate memory for 5 strings lines = new string[5]; } catch (bad_alloc e) { cout << e.what() << endl; return; } // write some text to the lines array lines[0] = "#include <stdio.h>"; lines[1] = "using namespace std"; lines[2] = "void main()"; lines[3] = "{"; lines[4] = "}"; // 3. Write strings to the TextFile2.txt if (SetStringsToFileS("TextFile2.txt", lines, 5)) cout << "OK!" << endl; else cout << "Error." << endl; // 4. Release memory allocated for lines array if (lines != nullptr) delete[] lines; }
⇑
6. Function ChangeStringInFileC(). Replacing a string in a text file
The example shows a function that replaces a line in a file at a given position. This function uses the following functions:
- CountLinesInFile() – determines the number of lines in the file (implemented in paragraph 3);
- GetStringsFromFileC() – returns the lines of the file as an array (implemented in step 4). Strings are represented by type char*.
This function does not use an additional file for copying. The function receives the lines of the file as an array of lines, which serve as a copy of the file. Then these lines are written to the same file, except for the line that needs to be replaced in the file. At the replacement position, the input replacement string is written. Thus, the line in the text file is replaced.
#include <iostream> using namespace std; // the <fstream> module is necessary for working with files #include <fstream> // A function that replaces a line in a file. // Parameters: // - filename - the name of file; // - position - the position of the line in the file to be replaced; // - str - line replacing the line in the file. // The function returns true if the string replacement operation was successful. bool ChangeStringInFileC(string filename, int position, string str) { // 1. Get file lines as an array char** lines; // array of file lines int count; // the number of lines in the file count = GetStringsFromFileC(filename, &lines); // get the array lines // 2. Checking if the file is read correctly if (count < 0) return false; // 3. Check if position 0 <= position < count is correct if ((position < 0) || (position >= count)) return false; // 4. Writing lines to a file ofstream F(filename); // open file for writing // 5. Checking if a file opened correctly - is_open() function if (!F.is_open()) return false; for (int i = 0; i < position; i++) F << lines[i] << endl; // output a string to a file // 6. Writing a line from position F << str.c_str() << endl; // the string str is written here // 7. Writing lines after position for (int i = position + 1; i < count - 1; i++) F << lines[i] << endl; // 8. Write the last line without the character '\n' F << lines[count - 1]; // 9. Close the file F.close(); // 10. Release the memory allocated for the strings for (int i = 0; i < count; i++) delete lines[i]; // 11. Release the pointer to the strings delete[] lines; }
Using this function can be, for example, the following:
void main() { // Replacing the input line in a file string filename = "TextFile1.txt"; // source file int pos = 5; // the original string position string str = "Hello world!"; // the original replacement string if (ChangeStringInFileC(filename, pos, str)) { cout << "OK!!!"; } else { cout << "Error"; } }
Optionally, you can change the input of the input data (file name, position, replacing the string).
⇑
7. Function RemoveStringFromFileByIndex(). Delete a line from a file by its number
Deleting a line from a file by its number can be performed according to the example of p. 6 (replacing a line in a text file).
The general algorithm is as follows:
- read all lines of the file into an array (list);
- remove string from the array;
- write the modified array back to the file.
To create a list of strings, you can use the GetStringsFromFileC() and GetStringsFromFileS() functions, which are described in paragraphs 3 and 4.
The text of the line delete function by its number is as follows.
#include <iostream> using namespace std; // the <fstream> module is necessary for working with files #include <fstream> // A function that deletes a line in a file at a given number, // line number starts at 0. // Function parameters: // - filename - name of the file from which the line is deleted; // - position - line number in the file to be deleted. // If the operation is successful, the function returns true; // if the row is not deleted, the function returns false. bool RemoveStringFromFileByIndex(string filename, int position) { // 1. Checking if string is specified correctly if (position < 0) return false; // 2. Additional variables string* lines; // array of strings int n; // number of lines into the file // 3. Read the number of lines in a file n = CountLinesInFile(filename); // invoke the function from paragraph 2 // 4. Checking if filename was read if (n == -1) return false; // 5. Checking if position is correct if (position >= n) return false; // 6. Get a list of lines of type string * n = GetStringsFromFileS(filename, &lines); // function from paragraph 4 // 7. Delete line at position for (int i = position; i < n - 1; i++) lines[i] = lines[i + 1]; // 8. Reduce the total number of strings n--; // 9. Write a list to a file - use the SetStringsToFileS() function bool res = SetStringsToFileS(filename, lines, n); // 10. Release array lines if (n > 0) delete[] lines; // 11. Return the result return res; }
Using a function can be, for example, as follows
void main() { // Removing the source line in the file string filename = "TextFile1.txt"; // source file int pos = 7; // specified position of the string if (RemoveStringFromFileByIndex(filename,pos)) { cout << "OK!!!"; } else { cout << "Error"; } }
⇑
8. Function InsertStringToFile(). Insert a line at a given position in a file
The approach is the same as in the previous paragraphs. You need to get the lines of the file as an array (type string or char*). Then you need to insert the string into the array and write the modified array of strings back to the file.
If the value of the insertion position is equal to the number of elements in the file, then the line is added to the end of the file.
#include <iostream> using namespace std; // the <fstream> module is necessary for working with files #include <fstream> // A function that inserts the specified string at the specified file position. // Function parameters: // - filename - the name of file; // - str - string to be inserted; // - position - position of string str. It is numbered from 0 to the number of lines in the file. // If the insert was successful, the function returns true. bool InsertStringToFile(string filename, string str, int position) { // 1. Additional variables int count; string* lines = nullptr; // list of file lines // 2. Get a list of lines from a file - a call to the function described in paragraph 4 count = GetStringsFromFileS(filename, &lines); // 3. Checking if the lines reading process is normal if ((count < 0)) return false; // 4. Check if position value is correct. // If positon == count, then the line is added to the end of the file. if ((position < 0) || (position > count)) return false; // 5. Create a new list of lines2, in which there is 1 more element string* lines2 = nullptr; try { // attempt to allocate memory for array lines2 lines2 = new string[count + 1]; } catch (bad_alloc e) { // if the attempt to allocate memory is unsuccessful, then exit the program cout << e.what() << endl; if (lines != nullptr) // release memory delete[] lines; return false; } // 6. Copy lines=>lines2 // 6.1. First copy to the position for (int i = 0; i < position; i++) lines2[i] = lines[i]; // 6.2. Add to lines2[position] string str lines2[position] = str; // 6.3. Copy the following strings for (int i = position; i < count; i++) lines2[i + 1] = lines[i]; // 7. Increase the total number of lines by 1 count++; // 8. Write lines to the file bool res = SetStringsToFileS(filename, lines2, count); // 9. Release memory, allocated for lines, lines2 if (lines != nullptr) delete[] lines; if (lines2 != nullptr) delete[] lines2; // 10. Return the result return res; }
The call to the InsertStringToFile() function in the main() function can be as follows.
void main() { // Paste the specified line at the specified file position string filename = "TextFile1.txt"; // source file int pos = 8; // specified position of the string string s = "Hello"; // insertion string if (InsertStringToFile(filename, s, pos)) { cout << "OK!!!"; } else { cout << "Error"; } }
⇑
9. Function SwapStringsInFile(). Swap two lines in a file
The algorithm of the SwapStringsInFiles() function is as follows:
- Read the lines of the file to the array.
- Change the lines in the array.
- Write the modified array back to the file.
The text of the string exchange function is as follows.
#include <iostream> using namespace std; // the <fstream> module is necessary for working with files #include <fstream> // A function that swaps two lines at specified positions. // Parameters: // - filename - the name of the file; // - pos1 - line position 1 (numbered from 0); // - pos2 - line position 2 (numbered from 0); // If the swapping was successful, then the function returns true. Otherwise false. bool SwapStringsInFile(string filename, int pos1, int pos2) { // 1. Check if pos1, pos2 are correct if ((pos1 < 0) || (pos2 < 0)) return false; // 2. Additional variables int count; string* lines = nullptr; // array of file lines string s; // 3. Get array of file lines count = GetStringsFromFileS(filename, &lines); // function from paragraph 4 // 4. Checking whether reading from a file has been successful if (count < 0) return false; // 5. Check if pos1, pos2 are within count if (pos1 >= count) return false; if (pos2 >= count) return false; // 6. Swap lines[pos1] and lines[pos2] s = lines[pos1]; lines[pos1] = lines[pos2]; lines[pos2] = s; // 7. Write an array of lines back to the file bool res = SetStringsToFileS(filename, lines, count); // 8. Release memory allocated for the array lines if (lines != nullptr) delete[] lines; // 9. Return the result return res; }
The call to the SwapStringsInFile() function from the main() function can be as follows
void main() { // Swap two lines in a file string filename = "TextFile1.txt"; // source file int pos1 = 2; // position 1 of line int pos2 = 7; // position 2 of line if (SwapStringsInFile(filename,pos1, pos2)) { cout << "OK!!!"; } else { cout << "Error"; } }
⇑
10. Function ReverseStringsInFile(). Reversing file lines (rearranging file lines in reverse order)
The algorithm of the method is as follows:
- read lines from a file and write them to an array;
- swap the elements of the array so that the rows of the array are placed in the reverse order;
- write modified array back to file
The text of ReverseStringsInFile() function is as follows.
#include <iostream> using namespace std; // the <fstream> module is necessary for working with files #include <fstream> // A function that reverses file lines in reverse order. // Parameters: // - filename - the name of the file. // If the operation is successful, the function returns true. bool ReverseStringsInFile(string filename) { // 1. Additional variables int count; string* lines = nullptr; string s; // 2. Read lines from the file count = GetStringsFromFileS(filename, &lines); // 3. Checking if rows were read correctly if (count <= 0) return false; // 4. Reversing the array lines for (int i = 0; i < count / 2; i++) { s = lines[i]; lines[i] = lines[count - i - 1]; lines[count - i - 1] = s; } // 5. Write array lines to the file bool res = SetStringsToFileS(filename, lines, count); // 6. Release memory, allocated for array lines if (lines != nullptr) delete[] lines; // 7. Return the result return res; }
Using ReverseStringsInFile() could be, for example, the following
void main() { // Reversing the lines of a file string filename = "TextFile3.txt"; // source file if (ReverseStringsInFile(filename)) { cout << "OK!!!"; } else { cout << "Error"; } }
⇑
11. Function SortStringsInFile(). Sort lines in a file
The example demonstrates sorting file lines using the insert method. Previously, the lines are copied to the array and sorted there. Then, the sorted array of strings is written back to the file.
#include <iostream> using namespace std; // the <fstream> module is necessary for working with files #include <fstream> // The function of sorting lines in a file by the insert method. // Parameters: // - filename - the name of a file. // If the sorting occurred correctly, then the function returns true. bool SortStringsInFile(string filename) { // 1. Additional variables int count; string* lines = nullptr; string s; // 2. Read lines from file to array lines count = GetStringsFromFileS(filename, &lines); // function from p.4 // 3. Checking if lines were read correctly if (count < 0) return false; // 4. Sort lines in file ascending by insertion for (int i = 0; i < count - 1; i++) for (int j = i; j >= 0; j--) if (lines[j] > lines[j + 1]) { s = lines[j]; lines[j] = lines[j + 1]; lines[j + 1] = s; } // 5. Write sorted array of lines to file bool res = SetStringsToFileS(filename, lines, count); // 6. Release memory allocated for array lines if (lines != nullptr) delete[] lines; // 7. Return the result return res; }
Using a file in the main() function
void main() { // Sort lines in a file string filename = "TextFile4.txt"; // source file if (SortStringsInFile(filename)) { cout << "OK!!!"; } else { cout << "Error"; } }
⇑
Related topics
- C++ File System. General concepts. Examples. Open/close file
- Examples of using C++ for working with files
⇑