Reputation: 33
I've been trying to solve this problem without using pointers, only with the basics (I'm a student) but I can't fine the solution.
void ReverseFile() {
FILE *originalM, *fin;
fopen_s(&originalM, "original.txt", "r");
fopen_s(&fin, "inverted.txt", "w");
char arr[100];
for (int i = 0; i < 100 && !feof(originalM); i++)
{
fscanf_s(originalM, "%c ", &arr[i]);
cout << arr[i] ;
}
cout << endl;
fclose(originalM);
for (int i = 0, k = 100; i < 100; i++, k--)
{
arr[k] = arr[i];
cout << arr[k];
}
fclose(fin);}
So far I have this function and one file of text (originalM.txt) which contains chars (with a space in between):
e e a a e e a a e e a a
In the first loop I get each char of the file and save it in the array. The problem comes in the second loop, where I want to reverse them. How can I solve this? I was trying to create a new array and store the chars but that doesn't work. Also I was trying to print it into the new file with this:
fprintf(fin, "%c ", &arr[k]);
I will be grateful for any help.
Upvotes: 0
Views: 136
Reputation: 98
Why not just save it in reverse order?
void ReverseFile() {
FILE *originalM, *fin;
fopen_s(&originalM, "original.txt", "r");
fopen_s(&fin, "inverted.txt", "w");
char arr[100];
for (int i = 0; i < 100 && !feof(originalM); i++)
{
fscanf_s(originalM, "%c ", &arr[i]);
cout << arr[i] ;
}
cout << endl;
fclose(originalM);
for (int k = i - 1, k >= 0; k--)
{
cout << arr[k];
}
fclose(fin);
}
Upvotes: 0
Reputation: 6046
In C++ and by using vector and stream iterators, you can do this (generalized for arbitrary number of characters):
void reverseFile(const string& in, const string& out)
{
ifstream input(in);
ofstream output(out);
istream_iterator<char> inStart(input), inEnd;
// load from the input file
vector<char> data(inStart, inEnd);
// copy back to the output file in reversed order
copy(data.rbegin(), data.rend(), ostream_iterator<char>(output));
}
If you'd like to retain the spaces in between the characters, the ostream_iterator
also supports a delimiter
parameter, so to retain spaces, you can simply add it to the line:
copy(data.rbegin(), data.rend(), ostream_iterator<char>(output, " "));
Upvotes: 4
Reputation: 93364
You can use std::reverse
to reverse arr
in-place. Unless you're always sure that all 100
values of arr
will contain meaningful values, you need to keep track of how many values you read.
Everything becomes trivial when you use idiomatic C++:
std::ifstream
and std::ofstream
can be used for file input/output.
std::vector
can be used as a generic resizable array.
std::ostringstream
can be used to load the entire original file into memory.
void ReverseFile()
{
std::ifstream ifs{"original.txt"};
// Read from `ifs` into a `arr` vector.
// (From "http://stackoverflow.com/questions/7241871").
std::ostringstream oss;
ss << file.rdbuf();
const auto& s = ss.str();
std::vector<char> arr(s.begin(), s.end());
// Reverse `arr` in place:
std::reverse(std::begin(arr), std::end(arr));
// Save `arr` to file.
std::ofstream ofs{"inverted.txt"};
for(auto x : arr) ofs << x;
ofs.flush();
ofs.close();
}
Upvotes: 2
Reputation: 966
Okay, suppose you have read some string into array char arr[100];
. Now to reverse it you can use something like this:
size_t length = strlen(arr);
for (int i = 0; i < length / 2; ++i)
{
char swapChar = arr[i];
arr[i] = arr[length-i-1];
arr[length-i-1] = swapChar;
}
Instead of 3 statements inside of that for
loop you can use std::swap
:
std::swap(arr[i], arr[length-i-1]);
Another way is to use std::reverse
as already answered by @VittorioRomeo.
Edit 1: Thanks to @StoryTeller for pointing out that your array should be NULL-terminated in order for strlen
to work. So after you've read data (say l
characters) do arr[l] = '\0';
Upvotes: 0
Reputation: 1315
You're using this code to reverse:
for (int i = 0, k = 100; i < 100; i++, k--)
{
arr[k] = arr[i];
cout << arr[k];
}
Think of it. In first 50 iterations you rewrite first half of array with the data of a second part, mirrored, in second 50 iterations you rewrite the second part with what you have copied into the first. What you need here is:
for (int i = 0; i < 50; i++)
{
char tmp; //you can use std::swap instead.
tmp = arr[i];
arr[i] = arr[100-i];
arr[100-i] = tmp;
}
Solutions like std::reverse are better, of course.
Upvotes: 0