0

Hi I'm trying to read string from txt file and transform it into binary file which is bitset<12> string form.

int main()
{
using namespace std;

std::ifstream f("fruit.txt");
std::ofstream out("result.txt");

std::hash<std::string>hash_fn;

int words_in_file = 0;
std::string str;
while (f >> str){
    ++words_in_file;
    std::bitset<12>* bin_str = new std::bitset<12>[3000];
    int temp_hash[sizeof(f)];
    std::size_t str_hash = hash_fn(str);
    temp_hash[words_in_file] = (unsigned int)str_hash;
    bin_str[words_in_file] = std::bitset<12>((unsigned int)temp_hash[words_in_file]);
    out << bin_str[words_in_file] << endl;
    delete[] bin_str;
}
out.close();
}

but there is error. How can I change it?

jack
  • 11
  • 2
  • what kind of error? You should be more clear and provide some additional details – BiagioF Apr 12 '17 at 23:38
  • no operator "=" matches these operands operand types are: std::string = std::bitset<12U> this error – jack Apr 12 '17 at 23:40
  • [why `while (!f.eof())` is wrong](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – Barmar Apr 12 '17 at 23:41
  • You can't assign to `str.c_str()`. – Barmar Apr 12 '17 at 23:42
  • I changed it but still has same error – jack Apr 12 '17 at 23:43
  • What are you trying to do in the line `str.c_str() = string`? You've never assigned anything to `string`, so why are you trying to assign that to `str.c_str()`? – Barmar Apr 12 '17 at 23:43
  • I just want to get a data from file and convert into binary and save into bitset<12> string – jack Apr 12 '17 at 23:44
  • So you need to loop through the contents of `str` and assign to the elements of `string`. – Barmar Apr 12 '17 at 23:45
  • Yes!!That's what I want – jack Apr 12 '17 at 23:46
  • It's still unclear what you mean by converting to binary. Why are you using `bitset<12>`? Bytes are 8 bits, while Unicode characters can be multiple bytes. Why 12 bits in your bitset? – Barmar Apr 12 '17 at 23:47
  • Does this help? http://stackoverflow.com/questions/23142363/convert-char-or-string-to-bitset-in-c – Barmar Apr 12 '17 at 23:48
  • Because my data must be '000000000000' in this form – jack Apr 12 '17 at 23:48
  • That's why you should give meaningful names to your variables. Why do you have `str` and `string`? Call the bitset `bits` or something and then it becomes more clear - you're assigning the wrong way around and if you're trying to read a bitset then you'll need to use something like `bits = bitset<12>(str);` – Rostislav Apr 13 '17 at 00:28

1 Answers1

1

Here is some code that I wrote that turns the input file "file.txt" into binary. It does this by taking the ascii value of each character and representing that number as a binary value, although I'm not sure how to write bin_str to a file here.

#include <string>
#include <fstream>
#include <streambuf>
#include <bitset>
#include <iostream>

int main(){
    std::ifstream f("file.txt");
    std::string str((std::istreambuf_iterator<char>(f)),
                    std::istreambuf_iterator<char>());  // Load the file into the string
    std::bitset<12> bin_str[str.size()]; // Create an array of std::bitset that is the size of the string

    for (int i = 0; i < str.size(); i++) {
        bin_str[i] = std::bitset<12>((int) str[i]); // load the array
        std::cout << bin_str[i] << std::endl; // print for checking
    }
}

SIDE NOTE:

std::bitset<12> may not be what you want, if you look at ascii characters the highest number you can have is 127 and in binary that's only 7 digits so I'd assume you'd want something more like std::bitset<7> or std::bitset<8>

EDIT:

If you want to write it to a file you'll need to open a file with std::ios::binary and then loop through the array of bitsets and write their unsigned long representative, given from to_ulong(), as a const char pointer ((const char*)&ulong_bin). Now when you open the file with a binary editor you will see the difference between the binary write and the regular write, but you'll notice that programs like cat can still decipher the binary you've written as simple ascii letters.

std::ofstream out("file.bin", std::ios::binary);
for (int i = 0; i < str.size(); i++) {
    unsigned long ulong_bin = bin_str[i].to_ulong();
    out.write((const char*)&ulong_bin, sizeof(ulong_bin));
}

EDIT: Credit to @PeterT

It has come to my attention that VLAs, variable length arrays, are not supported in C++11 and up so the line std::bitset<12> bin_str[str.size()]; should be changed to one of the following:

std::bitset<12> *bin_str = new std::bitset<12>[str.size()]; // make sure you delete it later
// OR
std::vector<std::bitset<12>> bin_str(str.size());
// OR
std::unique_ptr<std::bitset<12>[]> str_ptr (new std::bitset<12>[str.size()]);
Chris
  • 3,287
  • 2
  • 16
  • 36
  • Thanks! but this line has some error std::bitset<12> bin_str[str.size()]; IntelliSense: function call must have a constant value in a constant expression How can fix this error? – jack Apr 13 '17 at 10:55
  • I also has this error when I run the code Unhandled exception at 0x0021BDBE in binaryFile.exe: 0xC0000005: Access violation reading location 0x000000B0. – jack Apr 13 '17 at 11:39
  • IntelliSense is probably just throwing a fit because std::bitset is a template so it thinks you're not making an array but rather trying to use the birder like `std::birder` but the code works regardless and if you're getting an access violation that means that somewhere in the code something is trying to access restricted memory which means a pointer somewhere wasn't initialized or something like that. Do you mind compiling with '-g' and debugging the whole thing until you find the exact line that causes the problem – Chris Apr 13 '17 at 13:28
  • Thanks again! I changed the code in my question but I can't get the proper result I think I'm doing wrong in for loop but I don't know what is wrong. I'd like to get the result for full word For example, fruit.txt has {apple, orange} so I want to get the binary for apple so it'll be bin_s[0] , bin_s[1] but the result of bin_s[0] and bin_s[1] is same.. – jack Apr 13 '17 at 15:28
  • 1
    `std::bitset<12> bin_str[str.size()];` is using variable length arrays which is a C-language feature that's not supported by all C++ compilers. Something that you can do with standard C++ is `std::vector> bin_str(str.size());` – PeterT Apr 13 '17 at 15:37
  • My bad, you're right, you could however make it a pointer and use new couldn't you. – Chris Apr 13 '17 at 15:50
  • 1
    yes `std::bitset<12>* bin_str = new std::bitset<12>[str.size()];` would be possible, but since you'd have to manually delete that, I would prefer just the vector. But if you're hell-bend on the array but still want RAII you could also do `std::unique_ptr[]> str_ptr (new bitset<12>[str.size()]);` – PeterT Apr 13 '17 at 15:59
  • I delete[] bin_str but it has triggered a breakpoint. I put std::bitset<12>* bin_str= new std::bitset<12>[str.size()+1]; and bin_str[str.size()] = '\0'; – jack Apr 14 '17 at 12:22
  • I don't think you need to null terminate it – Chris Apr 14 '17 at 12:31
  • So, do you mean I do not use bin_set[str.size()]='\0'? – jack Apr 14 '17 at 12:35
  • Yeah since it's not a c-string or anything like that you don't necessarily need to null terminate it – Chris Apr 14 '17 at 12:37
  • I've get a error Unhandled exception at 0x000EDB35 in myprogram.exe: 0xC0000005: Access violation writing location 0xB1514C80. It was because of the memory allocation, but I have no idea. – jack Apr 14 '17 at 12:41
  • Perhaps you could show me all of the code you have written so I can more understand how you're getting this error, preferably as an edit to the question – Chris Apr 14 '17 at 12:45
  • I changed it on my question – jack Apr 14 '17 at 13:03
  • You're not accessing the bitset array correctly and you're not accessing temp_hash correctly either, they're arrays so everything in the square brackets is an index so if you put in 0 then you get the first element in it. Also I don't think you really want to make an array of 3000 bitsets, I suggest you rewrite all of that code, remember bitset takes a integer (or character) as input and turns that into binary, so if you want to turn a number into binary you only need one bitset – Chris Apr 14 '17 at 13:28
  • @jack Also I think you probably don't want to hash your strings, when you hash something you can't reverse that. If you're trying to write the string out to a file in a binary format follow my answer, if you're trying to do something else please explain – Chris Apr 14 '17 at 13:38