Kamelo10
Kamelo10

Reputation: 33

How do I reverse the a array of chars and store them in a new file?

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

Answers (5)

wmc
wmc

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

EmDroid
EmDroid

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

Vittorio Romeo
Vittorio Romeo

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++:

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

Yuriy Ivaskevych
Yuriy Ivaskevych

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

Leontyev Georgiy
Leontyev Georgiy

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

Related Questions