0

I am trying to read a textfile, text.txt with text representing hexadecimal values:

0123456789abcdef 
0123456789abcdef
0123456789abcdef
0123456789abcdef
0123456789abcdef
0123456789abcdef
0123456789abcdef 

I am supposed to read this file and use ofstream to write to a new file output.txt to write the binary equiavalent of these hexademical values, with - representing 0's and # representing 1's.

Example:

0 = ----
1 = ---#
2 = --#-
...
F = ####

And my output for output.txt is

---#--#---##-#---#-#-##--####---#--##-#-#-####--##-####-####

when it should be

---#--#---##-#---#-#-##--####---#--##-#-#-####--##-####-####
---#--#---##-#---#-#-##--####---#--##-#-#-####--##-####-####
---#--#---##-#---#-#-##--####---#--##-#-#-####--##-####-####
---#--#---##-#---#-#-##--####---#--##-#-#-####--##-####-####
---#--#---##-#---#-#-##--####---#--##-#-#-####--##-####-####
---#--#---##-#---#-#-##--####---#--##-#-#-####--##-####-####
---#--#---##-#---#-#-##--####---#--##-#-#-####--##-####-####

My logic is there, but it seems that output.txt only writes the first line of text.txt. This makes me believe that I am only reading the first line.

I am forced to use c-style strings, hence the char array I am reading into.

Here is my code

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
    ifstream myfile;
    myfile.open("test.txt");

    char words[10001] = {'\0'}; //c-style string
    if (myfile.is_open())
    {
        while (!myfile.eof())
        {
            myfile >> words; //read myfile text into char words[]

            ofstream outfile;
            outfile.open("output.txt"); //ofstream to output.txt based on character in words[]


            for (char c : words) //the ofstream to output.txt based on char c in words
            {
                if (c == '0')
                    outfile << "---#";
                else if (c == '2')
                    outfile << "--#-";
                else if (c == '3')
                    outfile << "--##";
                else if (c == '4')
                    outfile << "-#--";
                else if (c == '5')
                    outfile << "-#-#";
                else if (c == '6')
                    outfile << "-##-";
                else if (c == '7')
                    outfile << "-###";
                else if (c == '8')
                    outfile << "#---";
                else if (c == '9')
                    outfile << "#--#";
                else if (c == 'a')
                    outfile << "#-#-";
                else if (c == 'b')
                    outfile << "#-##";
                else if (c == 'c')
                    outfile << "##--";
                else if (c == 'd')
                    outfile << "##-#";
                else if (c == 'e')
                    outfile << "###-";
                else if (c == 'f')
                    outfile << "####";
            }
        }
        myfile.close();
    }

    return 0;
}

I suspect it's the myfile >> words, but I am not entirely sure. I added a few comments to try and explain the route I went.

Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620
hacker
  • 13
  • 5
  • You read all the lines. It just that you for each line you create a new file overwriting the previous one. You should keep your file open instead of closing and overwriting it. – ALX23z Mar 19 '21 at 14:25
  • Why `if (c == '1')` case is omitted? Why not use `switch`? Why not use an array or [`std::map`](https://en.cppreference.com/w/cpp/container/map) as lookup table? – MikeCAT Mar 19 '21 at 14:25
  • @MikeCat also the representation has a simple rule - so he could make it much simpler with a basic loop. – ALX23z Mar 19 '21 at 14:27
  • @ALX23z thanks so much you're totally correct. not sure how that sneaked past me – hacker Mar 19 '21 at 14:34
  • @MikeCAT sadly cannot use any other data structures as we have not learned them – hacker Mar 19 '21 at 14:34
  • Your file is line-based, but you are not reading whole lines, just individual words, and you are not writing out any line breaks in the output file. Change `while (!myfile.eof()) { myfile >> words; ... }` to `while (myfile >> words) { ... }` or even `while (myfile.getline(words, sizeof(words)) ) { ... }`, and add `outfile << "\n";` after the `for` loop. – Remy Lebeau Mar 19 '21 at 16:18
  • Also, please don't make edits to a question that invalidate existing comments/answers. If you want to add new details, you should add it as an additional edit at the end of the question, not altering the original content. I have rolled back your previous edit. – Remy Lebeau Mar 19 '21 at 16:21

2 Answers2

2

You used

            ofstream outfile;
            outfile.open("output.txt");

inside the loop. This makes the file opened in each iteration and this will clear the contents of file. You should move this befoer the while loop.

Also note that your condition while (!myfile.eof()) is wrong. Instead of this, you should move the reading myfile >> words to the condition to check if reading is successful before using what is "read".

MikeCAT
  • 61,086
  • 10
  • 41
  • 58
  • thanks so much. i basically instantiate a new ofstream every time i loop and overrides the old one. just one more quick question if you don't mind: is there a way that I can check when I have reached the end of the line? my output works, but is really long on one line. would using ```getline()``` be the solution here? is that even possible without being able to ```#include ```? – hacker Mar 19 '21 at 14:35
0

I would suggest this approach for the file handling:

ifstream infile("infile.txt");
ofstream outfile("outfile.txt");

if(infile.is_open()){
    while(!infile.eof()){
        //do the readings
    }
}else
{
    cout << "ERROR::FILE NOT SUCCESFULLY OPENED";
}