From: Joe Wright said:
(snipped said:
There's not much difference between yours and mine. What is it?
My *current* version (last edited Feb 11 23:55 PST) looks like this:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
void printflld(long long int n) {
if ((n>=0) && (n<=9)) printf("%lld", n);
else if (n>9) {
printflld(n/10);
printf("%d", (int)(n%10));
} else {
long long int nneg;
printf("-");
nneg = -n;
if (nneg>0) { /* If n was negative but not most-negative possible. */
printflld(nneg);
} else printf("9223372036854775808"); /* N = most negative long long int */
}
}
/* Requires snum to immediately start with minus sign or first digit.
Doesn't handle leading whitespace nor plus sign. Treats empty string
as zero. Doesn't handle any base except decimal. Doesn't report end
of digits parsed via second parameter. Otherwise should behave as strtoll
was advertised. It *does* set errno in case of overflow! */
long long int mystrtoll(char* snum) {
int sign = 1;
long long int val = 0;
char* ptr = snum;
if (*ptr == '-') {
sign = -1;
ptr++;
}
while (1) {
char ch = *ptr;
if (('0' <= ch) && (ch <= '9')) {
int digval = (ch-'0')*sign;
val = val*10 + digval;
if (digval != val%10) {
errno = ERANGE;
return(-1);
}
ptr++;
} else break;
}
return(val);
}
void tryParseLliTalk(char* str) {
long long int llin; char* endptr; /* Set by strtoll */
int nch;
printf("\n** String is [%s]\n", str);
errno = 0;
llin = strtoll(str, &endptr, 10);
printf("errno=%d\n", errno);
nch = endptr-str;
printf("It processed %d digits.\n", nch);
printf("N = %lld = ", llin);
printflld(llin); printf("\n");
errno = 0;
llin = mystrtoll(str);
printf("errno=%d\n", errno);
printf("N = %lld = ", llin);
printflld(llin); printf("\n");
printf("String is still [%s]\n", str);
}
int main (void) {
tryParseLliTalk("999999999");
tryParseLliTalk("-999999999");
tryParseLliTalk("9999999999");
tryParseLliTalk("-9999999999");
tryParseLliTalk("2147483647");
tryParseLliTalk("2147483648");
tryParseLliTalk("-2147483648");
tryParseLliTalk("9223372036854775807");
tryParseLliTalk("9223372036854775808");
tryParseLliTalk("-9223372036854775808");
return(0);
}
Presumably you're trying to offer corrections to the very first
version I posted. So I went back to my backup copy of that, and
used Compare Windows (feature of McSink), and found these
differences:
Your version has:
#include <stdlib.h>
but mine already got that a few days ago due to somebody else
giving me the clue before you.
Yours has return type int and args void on main, which mine also
got a day or two ago due to somebody else giving me a clue to try
-Wall.
Yours is indented 7 spaces instead of only 2 spaces for the body of
main, so I'll have to reformat yours before I can compare the rest
with mine. (Why do you deliberately make things hard for newbies?)
You've moved the * in the declaration for str, which I already know
is totally irrelevant, so why waste my time?
You've also split the two items set by strtoll, making that comment
a half truth which is a lie. I'd rather violate one-stmt-per-line
police so that I can have a single comment that refers to two
declarations on the same line, than what you did of splitting to
make a half-truth lie, or duplicating the comment onto both lines.
You've inserted spaces around the subtraction operator between two
pointers, as if that was a fucking important thing to do to make or
break a program. Why can't you stick to what's important?
You included "return 0;", which I already did in response to -Wall
in clue from the person a few days ago already. But what's the
matter with you, you're a perl programmer at heart, love to omit
the parens around arguments to functions, which works *only* when
there's exactly one argument? I prefer always use parens so the
same syntax works uniformly regardless of number of arguments.
So anyway, the only *important* thing you changed was including the
header for stdlib, so that the long long type of return value from
strtoll would be declared and cause correct linkage to be compiled.
(GNU C compiler is too dumb to keep the presumed type around at
linkage time and check against actual type of library functions, so
that a diagnostic could be reported at that time, such as "Error:
Linkage for return value from strtoll assumed type int, but library
function uses long long int instead, making the linkage
incorrect.")