Hey, I have an array of ints that are read from a file then stored in an unsigned char array. The array is declared in a static link. The pointer is then passed to main.

Main then calls a DLL which will process the information that is stored in the unsigned char. I'm having problems converting from the unsigned char into the int array.

What I have so far:

myStream.seekg (0, ios::end);//moves to the end of the file.
			fileSize = myStream.tellg();//gets the size of the file in bytes.
			myStream.seekg(0, ios::beg);//return to begginning.
			
			size = fileSize +1;//plus one for terminating character

			imgArray = new unsigned char *[size];

			myStream.read(reinterpret_cast<char *> (imgArray),(size)*sizeof(unsigned char));

This is the code that reads it into the array.

void DLL_Cubic(C1dArray* imgArray)
{
	int size;
	int *pArray;

	size = imgArray->getSize();

	pArray = new int [size];

}

Start of the DLL and the int that will store the array.

What kind of conversion would work to put it back into the array? Scratching my head at this one. Thanks in advance.

well if you want to convert a char to an int you have to do this

char temp = '2';
int number = temp - '0';  // number is now 2
// if you do this
int number = temp;  // number is now 50

You will have to post some of the contents of the file before we can tell you how to convert it. If its somethng like this:

123
456
789
10
20

You can use std::stringstream class to convert it from unsigned char* to an int array after its been read into one huge buffer. Or you could read it directly into the int array.

Contents are just numbers like:
12
-4
87
99
-3
Etc.
It's been read into one huge buffer but I want to be able to manipulate each individual int once it is in the array. Whats the best way to read it directly in? Would it be to use "sizeof (int)" ?

To read it directly into an int array

#include <vector>
#include <fstream>
using std::vector;
using std::ifstream;

int main()
{
   vector<int> ay;
   ifstream in("file.txt");
   if( in.is_open() )
   {
     int n;
     while( in >> n )
        ay.push_back(n);
   }
}

Cheers but I need to use an unsigned char array. Store the ints in the array (which is working so far) and then extract into an int array later in the program.

as I said before you can use streamstring class to do that

#include <sstream>
...
int main()
{
   vector<int> nums;
   int n;
   unsigned char buf[] = "12 23 45 67 -12"; // read from a file
   stringstream str;
   str << buf; 
   while( str >> n )
      nums.push_back(n);
}

That doesn't seem to be working is there a way to do it without vectors?

The code you posted is a bit weird, what is C1dArray?

Anyhow, simply put:

...
imgArray = new unsigned char *[size];

myStream.read(reinterpret_cast<char *> (imgArray),(fileSize)*sizeof(unsigned char)); //notice fileSize not size
//set the nullterminating char, if you really need it (IMO you don't).
imgArray[size-1] = 0;

int* pArray = new int [size];
for(int i=0; i<size; ++i)
  pArray[i] = imgArray[i];

C1dArray is a class. The class is passed and in the class is a pointer to an unsigned char array. Compiler throws an error "cannot convert from unsigned char to char" when I do this.

Ok, it needs to be explicit:

pArray[i] = int(imgArray[i]);

That solved the compiler error but the number that it is reading in is far to large. I have to access the array using a member function:

imgArray->get1dArray()

So it would be:

for(i=0; i<size; i++){
	pArray[i] = int(imgArray->get1dArray()[i]);
	}

Would "sizeof int" solve the problem some how? It's coming together I'm just not sure how to overcome this barrier. Thanks in advance.

@Mike: All that loop you posted will do is store each digit of the character array in an element of the int array. That isn't what he wants. Each integer in the character array has to be converted from ascii representation to int and the result stored in an array.

There are at least two ways to do it

  1. I already posted one method using stringstream and will not repeat it.
  2. Something like what Mike posted but use atol() or strtol() to convert from ascii to int.

>>Would "sizeof int" solve the problem some ho
No. And neither will typecasting.

I've tried the vector method like this but it doesn't seem to read in the whole array.

vector<int> vArray;
	int n;
	
	stringstream str;
   str << imgArray->get1dArray(); 
   while( str >> n )
      vArray.push_back(n);

How would the atoi method work in this scenario?

Actually the vector method does seem to make most sense and the code you provided does work but not in this program and I can't for the life of me understand why.

Post your program and text file.

Ok it will be a bit of a long post. I'm only using usigned chars because I was given a bit of the program to begin with and had to fill out the blanks.

C1dArray::C1dArray()
{	
	size = 0;
}	
C1dArray::C1dArray(int size)
{
	imgArray = new unsigned char *[size];
}
C1dArray::~C1dArray()//Destructor
{
	delete (imgArray); 
}
int C1dArray::getSize()
{
	return size;	
}
unsigned char ** C1dArray::get1dArray()
{
	return imgArray;	
}
void C1dArray::set1dArray(unsigned char **uc_img)
{	
	**imgArray = **uc_img;
}
int C1dArray::LoadC1dArray(char *imgName)
{
		int fileSize = 0;
	
		ifstream myStream;
		myStream.open(imgName, ios::binary);//opens input stream with given file name.

		if(!myStream){//File load error
			cout << "Unable to open file with the name " << imgName << endl;
			system("pause");
			
			return(0);//exit
		}
		else {				
		
			myStream.seekg (0, ios::end);//moves to the end of the file.
			fileSize = myStream.tellg();//gets the size of the file in bytes.
			myStream.seekg(0, ios::beg);//return to begginning.
			
			size = fileSize +1;//plus one for terminating character

			imgArray = new unsigned char *[size];

			myStream.read(reinterpret_cast<char *> (imgArray),(size)*sizeof(unsigned char));//reads the whole file into pArray	
			
			cout << "File " << imgName << " was loaded" << endl;
			cout.write(reinterpret_cast<char *> (imgArray),(size-1));//debug (  remove  )
		
			system("pause");
			
			return(1);//exit
		}

}

The class definitions stored in static link.

#include "stdafx.h"
#include <iostream>
#include "C1dArray.h"
#include "Cubic.h"

using namespace std;

int main()
{
	C1dArray* imgArray = new C1dArray;//new instance of C1dArray class
	
	int select;
	char imgName[259];
	int state = 0;

	while (state == 0){

	cout << "1. Load 1dArray" <<endl;
	cout << "2. Exit" <<endl; 
	cin >> select;
	

		if (select == 1)
		{
			cout<< "Please enter a file name to load" <<endl;
			cin >> ws;
			cin.getline(imgName,259);
			state = imgArray->LoadC1dArray(imgName);//load array
			system("CLS");
			select = 0;
		}
			else if(select == 2)
			{	
				return 0;
			}
			
		}

	if (state == 1)
	{
	cout << "1. Load 1dArray" <<endl;	
	cout << "2. Load DLL"<<endl;
	cout << "3. Exit" <<endl;
	cin >> select;			
		
			if(select == 2)
			{	
				DLL_Cubic(imgArray);
			}


	}


}

Main so far.

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <sstream>
#include "C1dArray.h"
#include "Cubic.h"

using namespace std;

void DLL_Cubic(C1dArray* imgArray)
{
	
	vector<int> vArray;
	int n;
	int i;
	
	stringstream str;
	str << imgArray->get1dArray(); 
	
	while( str >> n )
    vArray.push_back(n);

	system ("pause");

}

The DLL so far. I can get it to output the memory address of imgArray but not put contents into the string.

12
-30
4
-2
5
-6
73
-91
The contents of the text file.

why is DLL_Cubic() a void function? It doesn't do a thing with the array of ints after it is created.

What makes you think that the vector is not populated correctly? Your program isn't printing out the contentents so how would you know one way or the other?

You have to be careful about allocating memory in a DLL. Memory allocated in a DLL must be also destroyed in the same DLL. And likewise memory allocated in the main application program must also be destroyed in the program. Memory allocated in DLL can not be destroyed (deallocated) by the application program and vise versa.

The DLL will process the array of ints once it has been read in properly but it wont return anything to the main.

It isn't populated properly because I removed the code that out put the contents before I posted it. I tried cout << vArray[4]; but it crashes and says it is out of bounds. The array should be populated with 8 integers.

put that code from the DLL into the function that actually reads the file and see if it works.

Nope doesn't work. If I output the contents of the string it just prints out a NULL memory address 00000000.

vector<int> vArray;
	int n;
	int i;

	
	stringstream str;
   str << imgArray; 
   while( str >> n )
	   vArray.push_back(n);
  
   cout << str;

I placed it in the function after it has been read in.

It seems to be storing the memory address instead of the array but even failing at that. This is the right track just something isn't coming together right.

So close but still not cracked it any input would be much apreciated. I've re written alot of the function so that the DLL has to do less processing. What I have is:

int i;
		int fileSize = 0;
		unsigned char *charArray;
		ifstream myStream;

		myStream.open(imgName, ios::binary);//opens input stream with given file name.
		if(!myStream){//File load error
			cout << "Unable to open file with the name " << imgName << endl;
			system("pause");			
			return(0);//exit
		}
		else {				
		
			myStream.seekg (0, ios::end);//moves to the end of the file.
			fileSize = myStream.tellg();//gets the size of the file in bytes.
			myStream.seekg(0, ios::beg);//return to begginning.
			
			size = fileSize +1;//plus one for terminating character			

			charArray = (unsigned char *) new unsigned char [size];

			myStream.read(reinterpret_cast<char *> (charArray),(size)*sizeof(unsigned char));//reads the whole file into charArray.
			
			cout << "File " << imgName << " was loaded" << endl;
			
			img = new unsigned char *[size];
			
			for(i=0;i<size;i++){
				img[i] = charArray[i];}

Currently I get error cannot convert from "unsigned char to unsigned char*" I have been messing around with the pointers for hours with no luck.

>>img = new unsigned char *;
How is img declared? If its unsigned char* img; then the above line is incorrect. Remove the * from that line.

This works ok for me

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

int main()
{
    unsigned char* buf = 0;
    vector<int> vArray;
    ifstream in("textFile1.txt", ios::binary);
    if( in.is_open() )
    {
        in.seekg(0, ios::end);
        int sz = (int)in.tellg();
        in.seekg(0,ios::beg);
        buf = new unsigned char[sz+1];
        in.read((char *)buf, sz);
        buf[sz-1] = 0;
        cout << buf << '\n';
        stringstream str;
        str << buf;
        int n;
        while( str >> n)
            vArray.push_back(n);
        in.close();
        cout << "vArray.size() = " << vArray.size() << '\n';
        for(size_t i = 0; i < vArray.size(); i++)
            cout << vArray[i] << '\n';

    }

}

unsigned char is declared "unsigned char **img" I was given the definition headers and needed to fill them in and it was the only way it fit.

unsigned char ** C1dArray::get1dArray()
{
	// Add code here
	
}
void C1dArray::set1dArray(unsigned char **uc_img)
{	
	// Add code here
	
}

An example of the headers I was given.

The double star means that it is a two-dimensional array, that is, its an array of pointers to strings. Each line in the file occupies one of the pointers in that array.

unsigned char ** C1dArray::get1dArray()
{
    unsigned char** pArray = 0;
    unsigned char tempbuf[40] = {0};
    int size = 0;
    ifstream in("filename.txt"); // open the file in text mode
    if( in.is_open() )
    {
      while( in >> tempbuf )
      {
         pArray = realloc(pAray, (size+1) * sizeof(unsigned char *));
         pArray[size] = strdup(tempbuf);
         ++size;
      }
    }
    return pArray;
}

These two lines are causing:


Error 1 error C2440: '=' : cannot convert from 'void *' to 'unsigned char **'
Error 2 error C2664: 'strdup' : cannot convert parameter 1 from 'unsigned char [40]' to 'const char *'

while( myStream >> tempbuf )
      {
         img = realloc(img, (size+1) * sizeof(unsigned char *));
         img[size] = strdup(tempbuf);
         ++size;
      }
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.