patterncMinor
C library that converts integers to string and vice-versa
Viewed 0 times
viceconvertsversathatlibraryandintegersstring
Problem
I've created this little library to help ease myself (and for others, hopefully) with the pain of having to convert integers to string and vice-versa. It's written in C, and for maximum portability I decided to try and stick to C89 (no booleans yet by that time I believe). I'd like to ask you to give some of your comments and your recommendations, especially on the performance side.
Please note that when I was writing this code, my focus was on readability, self-documenting code and safety. Please also note that my naming convention varies very much from the C naming conventions that I'm sure a lot of you are used to seeing; e.g. abbreviated words instead of the complete words like "recv" for "receive", "u" for "unsigned", etc so if I confuse you with my naming convention then I hope you understand that readability was one of my primary concerns.
For some of the code which I thought some people might find unclear, I've added some comments in hopes of clearing up any confusion.
```
#include
#include
/CONSTANTS/
/ ERROR MESSAGES /
const char *invalidInputError = "convert.c: Unable to convert the input string into a valid number. Offending character has an ASCII value of %d. Valid ASCII values are from 48 to 57 (inclusive) and the null terminator '\0' at the end of the input string.";
const char *outOfBoundariesError = "convert.c: Value was outside of boundaries. Minimum value is 0 and maximum value is 4,294,967,295. Value was %ul";
/ BOUNDARIES /
#define CONVERT_UNSIGNED_INT_MAX 4294967295
#define CONVERT_SIGNED_INT_MIN -2147483648
#define CONVERT_SIGNED_INT_MAX 2147483647
#define CONVERT_UNSIGNED_MIN 0
#define CONVERT_ASCII_ZERO 48
#define CONVERT_ASCII_NINE 57
unsigned int FromStringToUnsignedInteger(char inputString[])
{
unsigned long long boundariesChecker;
unsigned int returnResult; returnResult = 0;
int counter; counter = 0;
// if the ASCII value is not between 48 and 57 inclusive, that's a
Please note that when I was writing this code, my focus was on readability, self-documenting code and safety. Please also note that my naming convention varies very much from the C naming conventions that I'm sure a lot of you are used to seeing; e.g. abbreviated words instead of the complete words like "recv" for "receive", "u" for "unsigned", etc so if I confuse you with my naming convention then I hope you understand that readability was one of my primary concerns.
For some of the code which I thought some people might find unclear, I've added some comments in hopes of clearing up any confusion.
```
#include
#include
/CONSTANTS/
/ ERROR MESSAGES /
const char *invalidInputError = "convert.c: Unable to convert the input string into a valid number. Offending character has an ASCII value of %d. Valid ASCII values are from 48 to 57 (inclusive) and the null terminator '\0' at the end of the input string.";
const char *outOfBoundariesError = "convert.c: Value was outside of boundaries. Minimum value is 0 and maximum value is 4,294,967,295. Value was %ul";
/ BOUNDARIES /
#define CONVERT_UNSIGNED_INT_MAX 4294967295
#define CONVERT_SIGNED_INT_MIN -2147483648
#define CONVERT_SIGNED_INT_MAX 2147483647
#define CONVERT_UNSIGNED_MIN 0
#define CONVERT_ASCII_ZERO 48
#define CONVERT_ASCII_NINE 57
unsigned int FromStringToUnsignedInteger(char inputString[])
{
unsigned long long boundariesChecker;
unsigned int returnResult; returnResult = 0;
int counter; counter = 0;
// if the ASCII value is not between 48 and 57 inclusive, that's a
Solution
Firstly, the interface:
You have no header for clients to include which defines the API clients are expected to use.
As you print a message and then return a value cannot be determined to be invalid, the client code has no chance of sensibly dealing with an overflow itself, and you're polluting stderr. They might want to print something in French.
It'd be better to return a value and a status, so the client code can deal with the error as it sees fit (and you should have a different state for overflow and invalid string).
The
You don't flag to the client that they're meant to free the string on exit. You must do that, or alternatively ask for a buffer to be supplied and do your sprintf into that.
Now to the implementation:
Use `
You have no header for clients to include which defines the API clients are expected to use.
As you print a message and then return a value cannot be determined to be invalid, the client code has no chance of sensibly dealing with an overflow itself, and you're polluting stderr. They might want to print something in French.
It'd be better to return a value and a status, so the client code can deal with the error as it sees fit (and you should have a different state for overflow and invalid string).
The
inputStrings should be char const * - you don't need to alter them, and this gives both you and the client confidence that you don't.You don't flag to the client that they're meant to free the string on exit. You must do that, or alternatively ask for a buffer to be supplied and do your sprintf into that.
Now to the implementation:
Use `
to work out the min/max possible values for integer types.
Initialisation of isNegative is potentially done twice, and isn't particularly readable. Perhaps write it like this:
int counter = 0;
int isNegative = 0;
if (inputString[0] == '-')
{
isNegative = !isNegative;
++counter;
}
Declare boundariesChecker in the block in which it is used.
int fred; fred = 0 reads strangely. What's wrong with int fred = 0;?
CONVERT_ASCII_ZERO should be '0' (and similarly for the NINE). Then you can drop the ASCII tag, as this'd work fine on EBCDIC machines.
returnResult = -returnResult would work fine and be probably more readable.
You don't check for malloc returning NULL.
Lastly, long long` isn't available in C89 except as an extension, so you can't use it for overflow checking.Code Snippets
int counter = 0;
int isNegative = 0;
if (inputString[0] == '-')
{
isNegative = !isNegative;
++counter;
}Context
StackExchange Code Review Q#63568, answer score: 3
Revisions (0)
No revisions yet.