While I won't address there correctness of your implementation of the "Floyd Warshall Algorithm", I do think I can help you read decimal values.
First, a couple of thoughts, pointers, hints. (1) your code is C and has nothing to do with C++, other than C++ originally being derived as a super-set of C many many years ago (it is now a language unto itself, but still maintains the ability to use the traditional C-library functions); (2) avoid using <conio.h>
, it is a windows-only header, and you can use the standard library function getchar()
to hold the terminal open until you press return instead of using getch()
, and there is simply no need for clrscr()
; and finally (3) avoid the use of global variables unless absolutely required. Declare your needed variables in main()
and pass them as parameters to any functions that require them.
To begin, the proper declarations for main
are int main (void)
and int main (int argc, char **argv)
(which you will see written with the equivalent char *argv[]
). note: main
is a function of type int
and it returns a value. See: C11 Standard §5.1.2.2.1 Program startup p1 (draft n1570). See also: See What should main() return in C and C++?.
Well done, when you need a constant using #define
is the proper way to define one (or you can use a global enum
to accomplish the same thing).
What values a variable can hold is determined by the type
you declare the variable to be. Your integer types are char, short, int, long, long long
(along with their unsigned
and exact-width
counterparts) and your types for holding decimal (floating-point) values are float
and double
. (generally 32-bit and 64-bit, respectively). So in your case, if you want w
and d
to be able to hold decimal values, you need to declare them with the proper type, e.g.
#define MAX 30
...
double w[MAX][MAX] = {{ 0.0 }}, /* double or float type */
d[MAX][MAX][MAX] = {{{ 0.0 }}}; /* to hold decimal values */
(it is always a good idea to initialize arrays to all zero to avoid an inadvertent attempt to read from an element that has not yet had its value set. This is also a difference between your global declarations (initialized zero by default) and when declaring the arrays within main()
with automatic storage duration)
When you are taking user input -- regardless of the function you use, you need to validate the return of the input function and validate the input itself if it is required to be within a given range, e.g.
printf ("enter the no. of vertices\n");
if (scanf ("%d", &v) != 1) { /* always validate scanf return */
fprintf (stderr, "error: invalid integer input for v.\n");
exit (EXIT_FAILURE); /* exit on failure - adjust as desired */
}
if (v < 0 || v > MAX) { /* validate v within range of MAX */
fprintf (stderr, "error: v not within 0 - %d.\n", MAX);
exit (EXIT_FAILURE);
}
To read double
values, you simply need to change your conversion specifier from %d
(used to read integer values) to %lf
(used to read double
values -- you omit the 'l'
modifier to read float
). You must still provide the same validation, e.g.
printf ("enter the weights\n");
for (i = 0; i < v; i++)
for (j = 0; j < v; j++)
if (scanf ("%lf", &w[i][j]) != 1) { /* use %lf for double */
fprintf (stderr, "error: invalid w[%d][%d].\n", i, j);
exit (EXIT_FAILURE);
}
Declaring w
and d
in main()
will require that you pass w
and d
as parameters to floyd()
, e.g.
void floyd (double d[][MAX][MAX], double w[][MAX], int v);
and you call it in main as:
floyd (d, w, v);
Putting it altogether, you could do something like the following (note: I'm on Linux and don't need getchar()
(or getch()
to hold the terminal open, so I have wrapped that call in preprocessor checks so that it is only called on windows):
#include <stdio.h>
#include <stdlib.h>
#define MAX 30
double min (double a, double b)
{
return a < b ? a : b;
}
void floyd (double d[][MAX][MAX], double w[][MAX], int v);
int main (void) {
int i, j, v = 0;
double w[MAX][MAX] = {{ 0.0 }}, /* double or float type */
d[MAX][MAX][MAX] = {{{ 0.0 }}}; /* to hold decimal values */
// clrscr(); /* there is no need for clrscr() */
printf ("enter the no. of vertices\n");
if (scanf ("%d", &v) != 1) { /* always validate scanf return */
fprintf (stderr, "error: invalid integer input for v.\n");
exit (EXIT_FAILURE); /* exit on failure - adjust as desired */
}
if (v < 0 || v > MAX) { /* validate v within range of MAX */
fprintf (stderr, "error: v not within 0 - %d.\n", MAX);
exit (EXIT_FAILURE);
}
printf ("enter the weights\n");
for (i = 0; i < v; i++)
for (j = 0; j < v; j++)
if (scanf ("%lf", &w[i][j]) != 1) { /* use %lf for double */
fprintf (stderr, "error: invalid w[%d][%d].\n", i, j);
exit (EXIT_FAILURE);
}
floyd (d, w, v);
#if defined (_WIN32) || defined (_WIN64)
getchar(); /* only keep console open on windows - using getchar() */
#endif
return 0;
}
/* pass d and w as parameters */
void floyd (double d[][MAX][MAX], double w[][MAX], int v)
{
int k = 0, i, j;
for (i = 0; i < v; i++) /* assign values for k = 0 */
for (j = 0; j < v; j++)
d[k][i][j] = w[i][j];
for (k = 1; k < v; k++) /* index from 1 based on params for min */
for (i = 0; i < v; i++)
for (j = 0; j < v; j++) { /* assign min k = 1, 2 */
d[k][i][j] = min(d[k-1][i][j], d[k-1][i][k]+ d[k-1][k][j]);
}
/* display in matrix */
for (k = 0; k < v; k++)
{
printf (" k = %d\n", k);
for (i = 0; i < v; i++) {
putchar ('\n'); /* use putchar for single characters */
for (j = 0; j < v; j++)
printf(" %6.2f", d[k][i][j]);
}
printf ("\n\n");
}
}
Example Use/Output
# ./bin/scanf_double_3d
enter the no. of vertices
3
enter the weights
1.1 2.2 3.3
4.4 5.5 6.6
7.7 8.8 9.9
k = 0
1.10 2.20 3.30
4.40 5.50 6.60
7.70 8.80 9.90
k = 1
1.10 2.20 3.30
4.40 5.50 6.60
7.70 8.80 9.90
k = 2
1.10 2.20 3.30
4.40 5.50 6.60
7.70 8.80 9.90
Look things over and let me know if this is what you intended and whether you have any further questions. Validating your algorithm is left to you.