I am modifying the WDK "genprint" Print Processor example. Everything is working great, and I can compile fine, but I am running into a snag with one thing.

Part of my modification knowingly triggers a print error, and Windows re-submits the print job automatically in the spool. I need to track the number of "copies" the user requested. I decided to put it in a text file, which I would decrement with each completed print.

Of course, having coded in PHP for so long, I have gotten VERY sloppy with data types (last real C programming was in 94). I can read and write into the file, but somewhere, somehow, I'm botching it up on the data type.

Code to READ the file in (strVal is a char):

hFile = CreateFile(cfnDest,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); 
	if(ReadFile(hFile,strVal,1024,&wmWritten,NULL)) {
		nCopies=(int)strVal;
	} 
	CloseHandle(hFile);

But nCopies is not an int like I want it. Please excuse my ignorance, but I am just trying to get the char strVal[1024] into an int.

Code that writes into the file:

StringCchPrintf(pszDest, cchDest, TEXT("%d"),nCopies);
		hFile = CreateFile(cfnDest,GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); 
		WriteFile(hFile,pszDest,(DWORD)(sizeof(pszDest)),&wmWritten,NULL);
		CloseHandle(hFile);

When I open the file in notepad.exe, the number from nCopies is there... so, this part works... I think.

Any help would be GREATLY appreciated.

Recommended Answers

All 9 Replies

is strval a single char that is a numeral character between 0 - 9?

then you cant just recast it as an int.

to convert a character numeral to it's integer value, you have to subtract 0x30 (decimal 48) from the character (ascii) value. int value = (int)strVal - 48;

Thanks for your quick reply. strVal originally comes from user input, so it could be 1, or 1000 (or anything inbetween).

Based on your (int)strVal-48 example, could I just loop through strVal subtracting 48, and multiplying based on the decimal place? I saw an example of this somewhere, I could dig it up again...

Somehow, I thought there would be an easier way to do this... take a char which as "123" and get 123 out of it.

No shorter way than the loop?

o wait. did you say strVal is a 1024 lenght character array??

that doesnt make sense....

how, exactly, is strVal defined?

okay... i thought 'strVal' was a single character.... so, no you dont have to convert each character and multiply by the power of 10. that's the long way. use the standard libraries instead.

such as the function "atol()" (Ascii TO Long integer) or "strtol()" (STRing TO Long integer) ... either will convert a string to its numeric (integer) value

of course, Unsigned Long Max is 4294967295, so it would be meaningless for your strVal to have a length of more than 11 characters.

.

Sorry, I failed to note that the genprint example in the WDK is in plain C... strtol is C++ right?

I did find RtlCharToInteger on MSDN just now... which appears to do something similar to strtol. I'll try that after I get doing with a quick test I'm doing using that -48 method you mentioned.

NO .... atol and strtol are not C++... they are part of the standard C library, <stdlib.h>.... understand that C++ is a "superset" of C. most everything in C is also in C++

so you dont have to manually convert each digit. I thought your variable was a single character, and that would have been the most simple way.

do feel free to go ahead and roll your own string-to-numeric converter if you like, there are worse things you could do, i suppose. but when you get tired of undefined behavior due to loosely written code, remember that a validated function is already available to you.


.

Boy, the last thing I want to do is roll my own function! I included stdlib.h and am working on testing those two functions you mentioned now (atol and strtol).

Guess I was making too many assumptions about C versus C++. I tried atoi and it was undefined... I didn't think to check my includes in this genprint example (stdlib was NOT included in this).

I gotta say though, I've added A LOT to the raw print processor so far, and I couldn't have done it without Daniweb.

NOTE: I also had to change the following in my original post:

WriteFile(hFile,pszDest,(DWORD)(sizeof(pszDest)),&wmWritten,NULL);

to:

WriteFile(hFile,pszDest,(DWORD)(sizeof(nCopies)),&wmWritten,NULL);

sizeof in the 3rd parameter needed to be my nCopies variable (for anyone who reads this down the road).

Ok, atoi worked for me.

hFile = CreateFile(cfnDest,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); 
	if(ReadFile(hFile,strVal,1024,&wmWritten,NULL)) {
		// file was there, and had something in it
		if(wmWritten>0) {
			nCopies=atoi(strVal);
		} 	
		
	} 
	CloseHandle(hFile);

(where int nCopies; and char strVal[100])

I also needed to check wmWritten, before just filling nCopies with whatever strVal was.

Thanks for your help!

no worries. glad it's working out for you.

For the record, "atoi()" has a problem that you can't telll the difference between an error (failure) and reading a valid zero (0).

"strtol()" is preferred. probably won't matter to you now, but someday it might.

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.