Red herring
The original code used int ans[200] = { 0 }; but in the light of some comments, that was changed to:
int ans[200];
for (int k = 0; i < 200; i++){
ans[k] = 0;
}
The loop is clearly erroneous; the index k should be tested and incremented, not i.
However, the original code was correct — it initializes all the elements of the array to 0 as desired. I'm sorry you got a 'bum steer' from some of the commentators.
Diagnosis
I think your main problem is in converting the second number into a string of digits.
for (int i = l1 + 3; i < length; i++){
s2[i] = str[i] - '0';
}
You need to assign to indexes in s2 in the range 0..l2, but you are indexing starting from l1+3, which leaves the start of s2 holding garbage. In the solution below, I took a lazy (but effective) way out: I created int z = 0; before the loop, and used s2[z++] = str[i] - '0';.
(Now I go back and reread kiner_shah's comment, I see that comment also diagnosed this flaw – but I confess I didn't understand what was said until re-reviewing the comments after posting this answer.)
Prescription
I added some assertions to ensure that things behaved as I expected. I added extensive debug printing. I also renamed l1 to len1 and l2 to len2; the 2-character names are just too easily confused with 11 and 12. I created a printing function to show the converted numbers. I could/should have created a function to encapsulate the conversion process.
The main problem was easily spotted when a simple test printed zeros for the second number, even though I'd typed 123 as the number. It was coincidence that it was zeros; the key point is that it wasn't 123 as expected.
Note that the printing has to deal with the special case of 0 as the result. The code that converts the string into a series of decimal digits could spot whether all the digits are zero (simply sum the converted digits; if the result is zero, all the digits are zero) and then special case the calculation (zero times anything is zero).
#include <assert.h>
#include <stdio.h>
/* Print digits - ensure each digit is visible with parentheses */
static void print_number(const char *tag, int len, int data[len])
{
printf("Number %s: [", tag);
for (int i = 0; i < len; i++)
printf("(%d)", data[i]);
printf("]\n");
}
int main(void)
{
char str[200];
if (fgets(str, sizeof(str), stdin) == NULL)
return 1;
int length;
for (length = 0; str[length] != '\0' && str[length] != '\n'; length++)
;
str[length] = '\0'; /* Zap newline */
printf("Calculation: [%s]\n", str); // Debug
int s1[101], s2[101];
int len1 = 0, len2 = 0;
/* This is fragile - it depends on the user getting the format right! */
for (int i = 0; i < length; i++)
{
len1++;
if (str[i] == '*')
{
len1 -= 2;
break;
}
}
assert(str[len1+0] == ' '); // Debug
assert(str[len1+1] == '*'); // Debug
assert(str[len1+2] == ' '); // Debug
len2 = length - len1;
len2 -= 3;
printf("Number 1: [%.*s]\n", len1, str); // Debug
printf("Number 2: [%.*s]\n", len2, &str[len1 + 3]); // Debug
for (int i = 0; i < len1; i++)
{
assert(str[i] >= '0' && str[i] <= '9'); // Debug
s1[i] = str[i] - '0';
}
print_number("1A", len1, s1); // Debug
int z = 0;
for (int i = len1 + 3; i < length; i++)
{
assert(str[i] >= '0' && str[i] <= '9'); // Debug
s2[z++] = str[i] - '0';
}
print_number("2A", len2, s2); // Debug
int ans[200] = { 0 };
int i, j, tmp;
/* Reverse digits of first number */
/* Need a function for this! */
j = len1 - 1;
i = 0;
while (i < j)
{
tmp = s1[i];
s1[i] = s1[j];
s1[j] = tmp;
i++;
j--;
}
/* Reverse digits of second number */
j = len2 - 1;
i = 0;
while (i < j)
{
tmp = s2[i];
s2[i] = s2[j];
s2[j] = tmp;
i++;
j--;
}
/* Raw multiplication - deal with carries later */
for (i = 0; i < len2; i++)
{
for (j = 0; j < len1; j++)
{
ans[i + j] += s2[i] * s1[j];
printf("[%d+%d] = %d\n", i, j, ans[i + j]);
}
}
/* Deal with carries */
for (i = 0; i < len1 + len2; i++)
{
int old1 = ans[i]; // Debug
int old2 = ans[i+1]; // Debug
tmp = ans[i] / 10;
ans[i] = ans[i] % 10;
ans[i + 1] = ans[i + 1] + tmp;
printf("Fixup %d: old (%d)(%d) new (%d)(%d)\n", // Debug
i, old1, old2, ans[i], ans[i+1]); // Debug
}
/* Find most significant digit */
for (i = len1 + len2; i >= 0; i--)
{
if (ans[i] > 0)
break;
}
printf("Significant digits = %d\n", i + 1); // Debug
/* Print digits in reverse order */
j = i; // Save starting point in j // Debug
if (i == -1) // Debug
putchar('0'); // Debug
else // Debug
{ // Debug
printf("Product : "); // Debug
for ( ; i >= 0; i--) // Debug
{ // Debug
printf("(%d)", ans[i]); // Debug
} // Debug
} // Debug
putchar('\n'); // Debug
i = j; // Recover starting point from j // Debug
printf("Product : ");
if (i == -1)
putchar('0');
else
{
for ( ; i >= 0; i--)
{
printf("%d", ans[i]);
}
}
putchar('\n');
return 0;
}
Sample test runs
Calculate 98 x 123
Calculation: [98 * 123]
Number 1: [98]
Number 2: [123]
Number 1A: [(9)(8)]
Number 2A: [(1)(2)(3)]
[0+0] = 24
[0+1] = 27
[1+0] = 43
[1+1] = 18
[2+0] = 26
[2+1] = 9
Fixup 0: old (24)(43) new (4)(45)
Fixup 1: old (45)(26) new (5)(30)
Fixup 2: old (30)(9) new (0)(12)
Fixup 3: old (12)(0) new (2)(1)
Fixup 4: old (1)(0) new (1)(0)
Significant digits = 5
Product : (1)(2)(0)(5)(4)
Product : 12054
Calculate 987654321 x 123456789012
Calculation: [987654321 * 123456789012]
Number 1: [987654321]
Number 2: [123456789012]
Number 1A: [(9)(8)(7)(6)(5)(4)(3)(2)(1)]
Number 2A: [(1)(2)(3)(4)(5)(6)(7)(8)(9)(0)(1)(2)]
[0+0] = 2
[0+1] = 4
[0+2] = 6
[0+3] = 8
[0+4] = 10
[0+5] = 12
[0+6] = 14
[0+7] = 16
[0+8] = 18
[1+0] = 5
[1+1] = 8
[1+2] = 11
[1+3] = 14
[1+4] = 17
[1+5] = 20
[1+6] = 23
[1+7] = 26
[1+8] = 9
[2+0] = 8
[2+1] = 11
[2+2] = 14
[2+3] = 17
[2+4] = 20
[2+5] = 23
[2+6] = 26
[2+7] = 9
[2+8] = 0
[3+0] = 20
[3+1] = 32
[3+2] = 44
[3+3] = 56
[3+4] = 68
[3+5] = 80
[3+6] = 72
[3+7] = 72
[3+8] = 81
[4+0] = 40
[4+1] = 60
[4+2] = 80
[4+3] = 100
[4+4] = 120
[4+5] = 120
[4+6] = 128
[4+7] = 145
[4+8] = 72
[5+0] = 67
[5+1] = 94
[5+2] = 121
[5+3] = 148
[5+4] = 155
[5+5] = 170
[5+6] = 194
[5+7] = 128
[5+8] = 63
[6+0] = 100
[6+1] = 133
[6+2] = 166
[6+3] = 179
[6+4] = 200
[6+5] = 230
[6+6] = 170
[6+7] = 111
[6+8] = 54
[7+0] = 138
[7+1] = 176
[7+2] = 194
[7+3] = 220
[7+4] = 255
[7+5] = 200
[7+6] = 146
[7+7] = 94
[7+8] = 45
[8+0] = 180
[8+1] = 202
[8+2] = 232
[8+3] = 271
[8+4] = 220
[8+5] = 170
[8+6] = 122
[8+7] = 77
[8+8] = 36
[9+0] = 205
[9+1] = 238
[9+2] = 280
[9+3] = 232
[9+4] = 185
[9+5] = 140
[9+6] = 98
[9+7] = 60
[9+8] = 27
[10+0] = 240
[10+1] = 284
[10+2] = 238
[10+3] = 193
[10+4] = 150
[10+5] = 110
[10+6] = 74
[10+7] = 43
[10+8] = 18
[11+0] = 285
[11+1] = 240
[11+2] = 196
[11+3] = 154
[11+4] = 115
[11+5] = 80
[11+6] = 50
[11+7] = 26
[11+8] = 9
Fixup 0: old (2)(5) new (2)(5)
Fixup 1: old (5)(8) new (5)(8)
Fixup 2: old (8)(20) new (8)(20)
Fixup 3: old (20)(40) new (0)(42)
Fixup 4: old (42)(67) new (2)(71)
Fixup 5: old (71)(100) new (1)(107)
Fixup 6: old (107)(138) new (7)(148)
Fixup 7: old (148)(180) new (8)(194)
Fixup 8: old (194)(205) new (4)(224)
Fixup 9: old (224)(240) new (4)(262)
Fixup 10: old (262)(285) new (2)(311)
Fixup 11: old (311)(240) new (1)(271)
Fixup 12: old (271)(196) new (1)(223)
Fixup 13: old (223)(154) new (3)(176)
Fixup 14: old (176)(115) new (6)(132)
Fixup 15: old (132)(80) new (2)(93)
Fixup 16: old (93)(50) new (3)(59)
Fixup 17: old (59)(26) new (9)(31)
Fixup 18: old (31)(9) new (1)(12)
Fixup 19: old (12)(0) new (2)(1)
Fixup 20: old (1)(0) new (1)(0)
Significant digits = 21
Product : (1)(2)(1)(9)(3)(2)(6)(3)(1)(1)(2)(4)(4)(8)(7)(1)(2)(0)(8)(5)(2)
Product : 121932631124487120852
$ bc <<< '987654321 * 123456789012'
121932631124487120852
$
Calculate 000 x 0000
Calculation: [000 * 0000]
Number 1: [000]
Number 2: [0000]
Number 1A: [(0)(0)(0)]
Number 2A: [(0)(0)(0)(0)]
[0+0] = 0
[0+1] = 0
[0+2] = 0
[1+0] = 0
[1+1] = 0
[1+2] = 0
[2+0] = 0
[2+1] = 0
[2+2] = 0
[3+0] = 0
[3+1] = 0
[3+2] = 0
Fixup 0: old (0)(0) new (0)(0)
Fixup 1: old (0)(0) new (0)(0)
Fixup 2: old (0)(0) new (0)(0)
Fixup 3: old (0)(0) new (0)(0)
Fixup 4: old (0)(0) new (0)(0)
Fixup 5: old (0)(0) new (0)(0)
Fixup 6: old (0)(0) new (0)(0)
Significant digits = 0
0
Product : 0
Observations on making debugging easier
This should get you going; there's a lot of refinements that could/should be made. This preserves most of your original code. It also shows you how I added code — assertions and printing operations — to see what was going on. When I saw this as the output from an early version of the code:
Calculation: [98 * 123]
Number 1: [98]
Number 2: [123]
Number 1A: [(9)(8)
Number 2A: [(0)(0)(0)
[0+0] = 0
[0+1] = 0
[1+0] = 0
[1+1] = 0
[2+0] = 0
[2+1] = 0
Fixup 0: old (0)(0) new (0)(0)
Fixup 1: old (0)(0) new (0)(0)
Fixup 2: old (0)(0) new (0)(0)
Fixup 3: old (0)(0) new (0)(0)
Fixup 4: old (0)(0) new (0)(0)
Significant digits = -1
Product :
it was easy to see where there was a problem (the second conversion loop), and from there it was easy to diagnose the main problem. When debugging, print inputs to make sure the program got what you expected. Print intermediate results to check that you get what you expected. Print final results carefully — make sure you are getting what you think you're getting. The use of (%d) illustrates the 'be careful'; when printing a digit string, it would have been easy to spot (19) is wrong whereas just 19 could be right or wrong, depending.
I'll also point you towards C #define macro for debug printing for information on how I'd use conditional compilation to deal with the debug printing if it was going to remain a useful part of a long-term program. You can find the relevant code in my SOQ (Stack Overflow Questions) repository on GitHub as files debug.c and debug.h in the src/libsoq sub-directory.