Thread: bits and files

  1. #1
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490

    bits and files

    Code:
    void load(istream& in) {
        letter.clear();
        code_g.clear();
        
        int x;
        in >> x; //no. of letters
        unsigned char y;
        vector <bool> z;
        unsigned char no_bits;
        for (int i=0;i<x;i++) {
          in >> y;
          letter.push_back(y);
          in >> no_bits;  //the number of bits
          for (int j=0;j<24;j++) {
    	if (j%8==0)
    	  in >> y;
    	if (j<no_bits) 
    	  z.push_back(y/(unsigned char)pow(2,j%8));
          }
          code_g.push_back(z); z.clear();
        }
      }
    Code:
      void print(ostream& out) {
        
        out << letter.size();
        for (int i=0;i<letter.size();i++) {
          out << letter[i];
          out << (unsigned char)code_g[i].size();
          unsigned char x=0;
          for (int j=0;j<24;j++) {
    	if (j==8 || j==16)  { out << x; x=0; }	
    	x |= (j < code_g[i].size() ? code_g[i][j] : 0) * (unsigned char)pow(2,j%8);
          }
          
          out << x;
        }
      }
    these functions are members of a class that has a table of bits and letters
    a 010111
    b 01
    c 1111
    etc...
    all the letters are in the letter[] vector array. the bits are in the code_g vector array; each element of the array is another array of boolean values representing bits. ie:
    vector <unsigned char> letter;
    vector <vector <bool> > code_g;

    i am sure the table is set up properly when created because there is another function which outputs the table in plaintext.
    my problem:
    void print() is supposed to output code to somewhere, like a file
    void load() is supposed to receive that code and translate it back into a table. somewhere between these two functions the bitstream is being translated wrong. i think it's on load(), but i can't be sure.

    any ideas on what's wrong?

  2. #2
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Code:
    >	if (j<no_bits) 
    >	  z.push_back(y/(unsigned char)pow(2,j%8));
    
    Change to:
    	if (j<no_bits) 
    	{
    	  z.push_back(y%2);
    	  y /= 2;
    	}

  3. #3
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490
    that doesn't help. (it doesn't really change anything). to get an idea on the problem, i have outputted the tables in plaintext to two text files: right and wrong. i'll attach them as txt files

    right:

  4. #4
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490
    wrong:


    the right attachment shows the table after being created without going through any file or input/output stream. the wrong attachment shows what the table looks like afterwards.

    i had to attach them seperately because there are special characters. (that shouldn't be there)
    Last edited by ygfperson; 04-22-2002 at 07:32 PM.

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Hmm, interesting. I created a simple example, and it works perfectly.

  6. #6
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490
    when you look at the files you notice that most of the table is the same. it's after 'r' that it goes wacky.

    is there any condition in the void load() function that would cause problems? i think i've localized the problem to that function.

    here's an attachment of the data in raw output form. (basically, cout is the ostream, and i use a command line to output it, in DOS, to rawfile.txt.
    Code:
    C:\...\program > raw.txt
    i was just thinking... could carriage returns be affecting things?
    another question: is outputting and inputting via the console accurate? or should i open a file and output like that?

  7. #7
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >i was just thinking... could carriage returns be affecting things?
    >another question: is outputting and inputting via the console accurate? or should i open a file and output like that?

    You are definitely going to have to use files. The console will not work.

    I investigated your problem, and using your right.txt and rawout.txt files, I got the same problems you had. As you said, it goes wacky after the 'r'.

    The solution is two things:

    1. open the file in binary mode
    ifstream in(filename,ios::binary);

    2. Change this read:
    in >> y;

    To this:
    in.read(&y,1);

    Since the file must be opened in binary mode, console mode probably will not work. Also, I would probably change all file input and output to read()'s and write()'s.

    By the way, it looks like the code it didn't like was 1011, which reversed is a 1101 (CR).

  8. #8
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Guess what? It also chokes on 0011, or reversed 1100 (FF), and 0101, or reversed 1010.
    Also 1001, and 1101.
    Last edited by swoopy; 04-23-2002 at 04:31 PM.

  9. #9
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >You are definitely going to have to use files. The console will not work.

    Although it apparently wrote the file out ok. So maybe using the console for output is ok.

  10. #10
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490
    ah
    this helps a lot
    thanks
    i'll post later with results

  11. #11
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490
    it works now. the results are identical to right.txt. thanks for your help

    one more thing, though. i can output through the console fine. but when i replace the cout arguement with myn. in detail:
    Code:
    ofstream myn("textout.txt",ios::binary);
    table->print(myn);
    myn.close();
    as you can guess, print(myn); goes to void print(ostream& out)
    for some reason, though, in the end there's the file "textout.txt" but there's nothing in it. it's size is 0. void print()'s only change was changing the int value to an unsigned char.
    any ideas?

  12. #12
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Glad to hear you got it working.

    As far as printing to a file, the code you're using is basically the same as mine, except I didn't use it as a class. I just did this:
    Code:
       ofstream out;
       out.open("binary.txt",ios::binary);
       print(out);
       out.close();
    If with the int to unsigned char change, it works through cout, it should also work with the ofstream. The only thing I can think of is maybe the file is still open from another stream.

  13. #13
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490
    i'll post my print function again (with the recent changes). maybe i put something there in my sleep...
    Code:
      void print(ostream& out) {
        
        out << (unsigned char)letter.size();
        for (int i=0;i<letter.size();i++) {
          out << letter[i];
          out << (unsigned char)code_g[i].size();
          unsigned char x=0;
          for (int j=0;j<24;j++) {
    	if (j==8 || j==16)  { out << x; x=0; }	
    	x |= (j < code_g[i].size() ? code_g[i][j] : 0) * (unsigned char)pow(2,j%8);
          }
          
          out << x;
        }
      }
    it can't be that this file is still open because it's only open in int main() with the commands i posted.
    i was thinking, maybe since it's binary mode i have to write things a certain way, like the changes that were made to load().

  14. #14
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Ok, I was able to run your code with no problems writing the file. Are you saying the file is completely empty???
    Here are some quick things to try:

    1. Leave off the ios::binary flag, and try the print() as it is, and see if you get any output.

    2. Comment your print() function, and make a dummy one with out << "Hello World" << endl and see if anything shows up.

    3. Change all outputs to out.write()'s and see if anything shows up.

  15. #15
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490
    it works now, after removing the ios::binary flag... strange...
    but it works, which is all i'm concerned about. thanks again for your help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. fscanf won't work for long files
    By tscalfa in forum C Programming
    Replies: 2
    Last Post: 03-30-2008, 05:38 PM
  2. Binary comparison from 2 files
    By Filly in forum C Programming
    Replies: 6
    Last Post: 01-16-2008, 06:49 AM
  3. Fseek and binary files
    By kambrian in forum C Programming
    Replies: 2
    Last Post: 02-06-2006, 04:20 PM
  4. Bits in files
    By robquigley in forum C++ Programming
    Replies: 1
    Last Post: 10-06-2003, 12:33 PM
  5. Replies: 0
    Last Post: 04-20-2003, 11:24 PM