I am trying to copy a string into an array then write bits out to a file accordingly. (compression assignment). here is the code

// strnewdup(const char* s) returns a copy of a
// null-terminated string, with the copy stored
// in the heap
char* strnewdup(const char* s)
{
	char* space = new char[strlen(s) + 1];
	strcpy(space, s);
	return space;
}

// putCodes(Node*& t, string* codes) traverses
// the tree t, recording the non-leaves(0) and
// leaves(1) into the correct letters code array
// to identify that letter
void putCodes(Node* t, string s, string* codes)
{
	if(t->kind == leaf)
	{
		const char* c = s.c_str();
		codes[(int)t->ch] = c;
	}
	else
	{
		putCodes(t->left, s+"0", codes);
		putCodes(t->right, s+"1", codes);
	}
}

ONE I AM HAVING TROUBLE WITH
// encFile(cont char* argv[], BFILE*& f, string* code)
// encodes the file argv and using the codes from code
// array puts them into file f
void encFile(const char* argv, BFILE*& f, string* code)
{
	string* s;
	s = code;
	const char* c;
	c = s.c_str();
	int length = strlen(s);
}

Here is the error I am getting

huffman.cpp: In function ‘void encFile(const char*, BFILE*&, std::string*)’:
huffman.cpp:164: error: request for member ‘c_str’ in ‘s’, which is of non-class type ‘std::string*’
huffman.cpp:165: error: cannot convert ‘std::string*’ to ‘const char*’ for argument ‘1’ to ‘size_t strlen(const char*)’
huffman.cpp:165: warning: unused variable ‘length’
make: *** [huffman] Error 1

They are both string* are they not? Also, I have tried const char* and that does not work as well. Any thoughts? the code that is passed is something such as "001" or "0011" and I want to somehow read this char by char and then use a writeBit(f,0) function to write that bit to a file f.

Dani AI

Generated

Good catches by and . To sidestep the pointer-to-std::string pitfalls entirely, pass your code table by reference and work with std::string values directly. That removes the need for any c_str/strlen conversions and keeps types consistent from end to end.

Here is a small, self-contained way to encode a file using the table you built in putCodes. It assumes you have 256 entries (one per byte value) and a writeBit(BFILE*, int) that buffers bits appropriately.

void encFile(const char* path, BFILE*& f, const std::vector<std::string>& codes)
{
    std::ifstream in(path, std::ios::binary);
    if (!in) return; // or handle error

    unsigned char ch = 0;
    while (in.read(reinterpret_cast<char*>(&ch), 1)) {
        const std::string& bits = codes[ch]; // use unsigned char for indexing
        for (std::string::size_type i = 0; i < bits.size(); ++i) {
            writeBit(f, bits[i] == '1');
        }
    }
}

A few practical notes that build on the thread:

  • As hinted, indexing a std::string is fine; just be careful when you also index your codes array. Cast the source byte to unsigned char so you never produce a negative index on platforms where char is signed.
  • When populating the table in putCodes, assign the std::string directly (no need to hop through const char*). It is both simpler and safer.
  • Writing ASCII '0' and '1' with ofstream will expand your data 8x. If your goal is compression, keep using writeBit so you emit actual bits. If you do not control writeBit, implement a tiny byte buffer that collects 8 booleans and writes one byte at a time.

If you must keep the pointer signature, prefer indexing rather than copying the pointer: const std::string& bits = code[static_cast<unsigned char>(ch)]; and then loop over bits. This avoids the original conversion errors and keeps the intent clear.

Recommended Answers

All 3 Replies

Dereference s before you try to get the c_str() method: c = (*s).c_str(); since s is a pointer to string not a string. Or c=s->c_str(); will work too I just thought the other form was more illustrative for your benefit.

Also, strlen won't give you the length of the std::string, use s->length() (same need to dereference) instead-- unless you meant to take strlen of c instead.

You do know you can say s[0], s[1], s[n] to get the characters of a string, don't you?

Dereference s before you try to get the c_str() method: c = (*s).c_str(); since s is a pointer to string not a string. Or c=s->c_str(); will work too I just thought the other form was more illustrative for your benefit.

Also, strlen won't give you the length of the std::string, use s->length() (same need to dereference) instead-- unless you meant to take strlen of c instead.

got it :) thank you. though i didnt use this method, instead i just used the ofstream feature of append. appreciate the feedback though :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.