Reputation: 825
I'm writing a program in C that converts a string of n characters into an integer only if this string's first character is the minus symbol. The program is the following:
#include <string.h>
#include <stdio.h>
#include <math.h>
int StringToInt(char *string){
int i=0;
int integer=0;
int length = strlen(string);
if (string[0]=='-'){
for (i=1; i<length; i++){
integer += (string[i]-48)*pow(10, (length-1-i));
}return (integer*(-1));
}else{
return 0;
}
}
My program works fine when I call the function above with a string with an odd value of string length, while otherwise it returns the right value but decremented by one. Now I'll make it clearer with an example: suppose I create a string called "Number" and I assign to this the number "-234". If we put this string in the function above, the string's length will be calculated as 4. The function in this case won't return -234, but -233. If, instead of -234, I had assigned to the string a number like "-1456", the function would have returned the correct number.
Upvotes: 1
Views: 50
Reputation: 4182
I suggest the next code, it's based in the recommendations made in comments:
#include <string.h>
#include <stdio.h>
int StringToInt(const char* string){
int lenght = strlen(string);
if (lenght && string[0] == '-'){
int integer = 0;
for (int i = 1; i < lenght; ++i) {
// Check if it is not a character valid.
if (string[i] < '0' || string[i] > '9') {
// Returns the integer processed so far.
return -integer;
}
integer = 10 * integer + string[i] - '0'; // Like John Bollinger suggests
}
return -integer;
} else {
return 0;
}
}
int main(int argc, char **argv) {
fprintf(stderr, "%d\n", StringToInt(""));
fprintf(stderr, "%d\n", StringToInt("-123"));
fprintf(stderr, "%d\n", StringToInt("-1736734"));
fprintf(stderr, "%d\n", StringToInt("-1999"));
fprintf(stderr, "%d\n", StringToInt("-123"));
fprintf(stderr, "%d\n", StringToInt("-234"));
fprintf(stderr, "%d\n", StringToInt("-180."));
fprintf(stderr, "%d\n", StringToInt("-200.99"));
fprintf(stderr, "%d\n", StringToInt("-aaa"));
const char* msg = "-301";
fprintf(stderr, "%d\n", StringToInt(msg));
return 0;
}
I suggest check if the character is not valid (i.e: it is not between '0' and '9'):
if (string[i] < '0' || string[i] > '9') {
// Returns the integer processed so far.
return -integer;
}
Once you find a character not valid, return the integer processed so far.
Output:
0
-123
-1736734
-1999
-123
-234
-180
-200
0
-301
Upvotes: 1
Reputation: 7437
I'm pretty sure it's just rounding errors. When you cast 0.999999 as an int you get 0. Thus, any floating point error that results in a number like 2047.999999 will be interpreted as 2047 instead of the more accurate 2048, which will look like it's decremented by 1.
As John Bollinger suggested in a comment, just add each character to 10 times the current value:
#include <string.h>
#include <stdio.h>
int string_to_int(char *string) {
int i=0;
int integer=0;
int length = strlen(string);
if (string[0] == '-') {
for (i=1; i<length; i++) {
integer = 10 * integer + string[i]-'0';
}
return -integer;
} else {
return 0;
}
}
int main(int argc, char **argv) {
if (argc < 2)
return 1;
printf("Result: %d\n", string_to_int(argv[1]));
return 0;
}
I prefer to say '0' rather than 48 since it clarifies your intent (converting a character to the digit it represents).
Upvotes: 2