Click here to Skip to main content
15,902,299 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi, I rather new in C++ but have a basic understanding of programming in terms of Java. Right now I am having problems trying to read data from disk. After reading the number of bytes from the file, I allocate memory via malloc and create a new string to store the string of data from file. Then i remove the white spaces and try to create the byte array, however it crashes when the character is invalid

this is the string of data in my readingfile.dat
10 02 01 02 03 04 0a 00 03 10


converting method to byte array
C++
void string_to_bytearray(std::string str, unsigned char* &array, int& size)
{
	int length = str.length();
	// make sure the input string has an even digit numbers
	if(length%2 == 1)
	{
		str = "0" + str;
		length++;
	}

	// allocate memory for the output array
	array = new unsigned char[length/2];
	size = length/2;

	std::stringstream sstr(str);
	for(int i=0; i < size; i++)
	{
		char ch1, ch2;
		sstr >> ch1 >> ch2;
		int dig1, dig2;
// crashes here when an invalid char was passed in
		if(isdigit(ch1)) dig1 = ch1 - '0';
		else if(ch1>='A' && ch1<='F') dig1 = ch1 - 'A' + 10;
		else if(ch1>='a' && ch1<='f') dig1 = ch1 - 'a' + 10;
		if(isdigit(ch2)) dig2 = ch2 - '0';
		else if(ch2>='A' && ch2<='F') dig2 = ch2 - 'A' + 10;
		else if(ch2>='a' && ch2<='f') dig2 = ch2 - 'a' + 10;
		array[i] = dig1*16 + dig2;
	}
}


my read file method
C++
unsigned long ReadFromDisk()
{

	FILE	*pFile;
	long	lSize;
	char	*pCharbuff;
	
	byte	abBuffer[128];
	
	pFile = fopen ( "W:\\SW\\readingfile.dat" , "rb" );

	fseek(pFile , 0 , SEEK_END);
	lSize = ftell (pFile);
	rewind(pFile);

	// allocate the buffer
	pCharbuff = (char*) malloc (sizeof(char)*lSize);

// problem is here, the file has only 29 bytes of data and yet it allocates extra 4 bytes, and when checking bytes if it is a digit or not, it gives an error
	fread (pCharbuff,1,lSize,pFile);

// sorry forgot this line
std::string strString(pCharbuff);

	// remove white spaces
	bool spacesLeft = true;
	std::string::size_type pos = 0;
	while(spacesLeft)
	{
		pos = strString.find(" ");
		if(pos != std::string::npos)
			strString.erase( pos, 1 );
		else
			spacesLeft = false;
	}

	unsigned char* array = NULL;
	int size;
	string_to_bytearray(strString, array, size);	

	return 0;
}


furthermore i wish to implement this as a thread, so i can read from the same postion i left off everytime. How do i do that? can i set some offset under fseek?
Posted
Updated 14-Nov-11 3:33am
v2
Comments
PrafullaVedante 14-Nov-11 5:45am    
What is isDigit function ??
Please post it too
Stefan_Lang 14-Nov-11 9:26am    
std::isdigit() checks if a character is a digit or not. See http://www.cplusplus.com/reference/clibrary/cctype/isdigit/

C++
fread (pCharbuff,1,lSize,pFile);

// remove white spaces
bool spacesLeft = true;
std::string::size_type pos = 0;
while(spacesLeft)
{
    pos = strString.find(" ");

Your string variable strString has not been initialised with the contents of the buffer read from the file.

[UPDATE]
The problem also is that you have not terminated your input data properly so the strString(pCharbuff); constructor is picking up garbage. Change the code as follows:
C++
pCharbuff = (char*) malloc (sizeof(char)* (lSize + 1));
fread (pCharbuff,1,lSize,pFile);
pCharbuff[lSize] = '\0';  \\ add null terminator to end of data
std::string strString(pCharbuff);

[/UPDATE]
 
Share this answer
 
v2
Comments
Zsefv2 14-Nov-11 9:34am    
updated the question, i forgot to convert pCharbuff to strString
Richard MacCutchan 14-Nov-11 12:25pm    
See my update above.
You wrote:
C++
// problem is here, the file has only 29 bytes of data and yet it allocates extra 4 bytes

See http://www.cplusplus.com/reference/clibrary/cstdio/ftell/[^] :

For text streams, the value is not guaranteed to be the exact number of bytes from the beginning of the file

I'm not sure what this means myself, but this could be due to control characters that are not visible in a text file, such as end of line, end of file, and the like. If that is the case, then eliminating spaces wouldn't be enough - you might also need to eliminate other whitespace characters.

To remove all whitespace you could try:
C++
str.erase(remove_if(str.begin(), str.end(), ::isspace), str.end());

(see http://stackoverflow.com/questions/83439/remove-spaces-from-stdstring-in-c[^])
 
Share this answer
 
Comments
[no name] 14-Nov-11 10:25am    
Parsing "rb" to fopen means the file is opened in binary mode though, not text mode. In this case ftell would give the correct value.
Stefan_Lang 15-Nov-11 5:21am    
Actually that might be the problem: fseek() and ftell will treat the file as binary and therefore count non-printable chars as actual data. The input is supposed to be text though, so the file should be opened and read as such!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900