0

Pretext: I am new to c++ coding and know arrays and strings. This professor showed how to input and output into files and gave us the following assignment.

Assignment question: Input a number in a file. Now imagine there is a staircase with the inputted number of steps. You can either step up one step and denote this by 'u' or you can take two steps up and denote this by 'd'. Find all possible combinations of this type and write them in a file.

Example: For n=1 the output should be 'u'; For n=2 the output should be 'uu d'; For n=3 the output should be 'uuu ud du' and so on.

My thought process: So this is basically a Fibonacci series. So just like fibonacci series i thought of a recursive algorithm. Here is what I came up with...

Code

#include<iostream>
#include<fstream>
using namespace std;
void staircase(int num, int count, char* c, int index, ofstream &file)
{
    char c1[num], c2[num];    
    for (int i = 0;i < num;i++) {
        c1[i] = c[i];
        c2[i] = c[i];
    }
    if (num - count == 2) {
        c1[index] = 'd';
        c2[index] = 'u';
        c2[index + 1] = 'u';
        file.open("output.txt", ios::app);
        file << c1 <<"  ";
        file << c2 <<"  ";
        file.close();
        return;


    }
    if (num - count == 1) {
        c2[index] = 'u';
        file.open("output.txt", ios::app);
        file << c2 <<"  ";
        file.close();
        return;

    }
    if (num - count > 2) {
        c1[index] = 'd';
        c2[index] = 'u';
        staircase(num, count + 2, c1, index+1,file);
        staircase(num, count + 1, c2, index+1,file);
    }
}
int main(){
    int num;
    cout<<"Input total number of stairs: ";
    cin>>num;
    fstream myfile;
    myfile.open("input.txt");
    myfile<<num;
    myfile.close();
    cout<<"Input is saved in file Directory   ";
    char c[num];
    ofstream file;
    file.open("output.txt");
    staircase(num, 0, c, 0, file);
}

Problem: When I wrote it without the file code and all it did fine and command prompt showed all the possible outputs. I also noticed for n=1 and n=2 it doesn't even print anything on the file. I feel like I'm missing somethings with fstream and cannot point it down. I tried to search google and stackoverflow. Thanks for helping me. Also following is the version without any files in it.

#include<iostream>
#include<fstream>
using namespace std;
void staircase(int num, int count, char* c, int index)
{
    char c1[num], c2[num];    
    for (int i = 0;i < num;i++) {
        c1[i] = c[i];
        c2[i] = c[i];
    }
    if (num - count == 2) {
        c1[index] = 'd';
        c2[index] = 'u';
        c2[index + 1] = 'u';
        for(int i=0;i<=index;i++)
        cout<<c1[i];
        cout<<" ";
        for(int i=0;i<=index+1;i++)
        cout<<c2[i];
        cout<<" ";
        return;


    }
    if (num - count == 1) {
        c2[index] = 'u';
        for(int i=0;i<index+1;i++)
        cout<<c2[i];
        cout<<" ";
        return;

    }
    if (num - count > 2) {
        c1[index] = 'd';
        c2[index] = 'u';
        staircase(num, count + 2, c1, index+1);
        staircase(num, count + 1, c2, index+1);

    }
}
int main(){
    int num;
    cout<<"Input total number of stairs: ";
    cin>>num;
    cout<<"Input is saved in file Directory   ";
    char c[num];
    staircase(num, 0, c, 0);
}
Rio
  • 23
  • 6
  • I am getting missing values on the output file. – Rio Feb 25 '20 at 15:10
  • Remove all uses of `open` and `close` from `staircase`. The file is already opened, and it will be closed automatically when `main` finishes. – molbdnilo Feb 25 '20 at 15:15
  • @molbdnilo for n=2 it is returning 'd uuo ' and for n=1 it is returning 'uúo '. I tried this before but getting extra characters. But for n>1 it is working fine though, I just checked. – Rio Feb 25 '20 at 15:19
  • Your functions are not identical - you removed a few loops for some reason - so it's not surprising that the results differ. Take your "cout version", add an `ostream &file` parameter, and replace `cout` with `file` in the function. (Using `ostream&` rather than `ofstream&` lets you pass `cout` to the function from `main` and verify the output without using a file.) – molbdnilo Feb 25 '20 at 15:29
  • 1
    You question seems to be about how to read/write to files. But there is a whole lot in there about your school assignement that is not really relevant to the question. Please read on how to make a [mcve]. – super Feb 25 '20 at 15:46
  • Sidenote: VLA:s (variable length arrays, such as `char c[num];` when `num` is not a `constexpr`) are not available in standard C++. Use `std::vector c(num);` instead. – Ted Lyngmo Feb 25 '20 at 16:11
  • @molbdnilo wait I didn't understand what you said. I was getting a feeling that the functions are not identical, but I am new so don't get what is going wrong. I just have to replace 'cout' with 'file'? – Rio Feb 25 '20 at 18:42
  • "_I was getting a feeling that the functions are not identical_" - Just run the two programs through a comparison program, like `diff`, and it'll tell you where the programs differ. One thing: You have `for` loops in the program streaming to `cout`. If that program works, just make that version of `staircase` take a parameter `std::ostream& os` and replace all `cout`s with `os` in the function. You can then call it with `cout` **or** your opened `file` and the result will be the same for both. – Ted Lyngmo Feb 25 '20 at 19:38
  • @molbdnilo thanks for the understanding I needed. Well the program works fine now after replacing cout with file. Thanks for helping me understand. But can I ask how to obtain advanced concepts like vla and constexpr and so on? Thanks for the positive help I got from you guys! – Rio Feb 25 '20 at 21:53

1 Answers1

0

In your description of the problem it sounds like the version streaming to std::cout does the job correctly. In that case, just add a parameter to staircase taking a std::ostream& and replace cout everywhere in the function with the ostream parameter. That way you can stream both to std::cout and opened std::ofstreams.

If you want to stay with standard C++, don't use VLA:s - use a std::vector<> instead. It has a lot of nice features, such as a member function called size() that you can use instead of having to pass num as a separate parameter together with your VLA.

Example:

#include <cstddef>
#include <fstream>
#include <iostream>
#include <vector>

// When using a vector, you don't need to pass in "num". The vector
// has a size() function that returns how many enements it contains.
// Also note the added std::ostream parameter for streaming to any ostream.
void staircase(size_t count, const std::vector<char>& c, size_t index, std::ostream& os)
{
    std::vector<char> c1 = c; // create a copy of c instead of manual looping
    std::vector<char> c2 = c; // create a copy of c instead of manual looping

    if(c.size() - count == 2) {
        c1[index] = 'd';
        c2[index] = 'u';
        c2[index + 1] = 'u';
        for(size_t i = 0; i <= index; ++i) os << c1[i];
        os << ' ';
        for(size_t i = 0; i <= index + 1; ++i) os << c2[i];
        os << ' ';
        return;
    }
    if(c.size() - count == 1) {
        c2[index] = 'u';
        for(size_t i = 0; i < index + 1; ++i) os << c2[i];
        os << ' ';
        return;
    }
    if(c.size() - count > 2) {
        c1[index] = 'd';
        c2[index] = 'u';
        staircase(count + 2, c1, index + 1, os);
        staircase(count + 1, c2, index + 1, os);
    }
}

int main() {
    size_t num;
    std::cout << "Input total number of stairs: ";
    std::cin >> num;

    // use a vector instead of a VLA:
    std::vector<char> c(num, 0);

    // Just call staircase with an open file instead of std::cout
    // if you want the output to a file.
    staircase(0, c, 0, std::cout);

    std::cout << '\n';
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • Thanks for the answer. Well thanks for suggesting . I will try and work it out. I am sure your way does the job. Can I ask something? Where do I learn advanced c++ stuff? I think I get most of the algorithms right and I can do basic programming okayish. I want to learn advanced concepts and their implementations. – Rio Feb 25 '20 at 21:49
  • You are welcome! Most people suggest getting [a good book](https://stackoverflow.com/a/388282/7582247) or two. Personally, I'm not so good with books, so I've just continued the way I started, by trying out stuff for fun. My way takes much longer than reading I'm sure... – Ted Lyngmo Feb 25 '20 at 21:56
  • yes did it. Also my way is kind of same, I never read a book on programming but I feel like people in stackexchange write so much different and andvanced codes. It aspires me to be better hence was my question. I guess I'll learn slowly too. – Rio Feb 25 '20 at 22:04
  • @Rio Yes, stack* is a great source of inspiration indeed. I feel I've learned a lot since I started frequenting SO - both by trying to understand other peoples answers and by trying to solve peoples problems myself. It's reading - but there are no books involved :-) – Ted Lyngmo Feb 25 '20 at 22:12