#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
int getdata (double a[][10], double b[])
{
   char fname[64];
   FILE *f;
   int i, j, n, rc;

   do {
      printf ("File: ");
      scanf ("%s", fname);
      if ((f = fopen (fname, "rt")) != NULL) break;
      printf ("Cannot open file %s\n", fname);
   } while (1);

   rc = fscanf (f, "%d", &n);
   if (rc != 1 || n < 1 || n > 10) {
      printf ("Error: illegal n value\n");
      return 0;
   }

   for (i = 0; i < n; i++) {
      for (j = 0; j < n; j++)
	 if (fscanf (f, "%lf", &a[i][j]) != 1) {
	    printf ("Error in coefficient (%d,%d)\n", i+1, j+1);
	    return 0;
	 }
      if (fscanf (f, "%lf", &b[i]) != 1) {
	 printf ("Error in right-hand side (%d)\n", i+1);
	 return 0;
      }
   }

   fclose (f);
   return n;
}

void printdata (int n, double a[][10], double b[])
{
   int i, j;

   for (i = 0; i < n; i++) {
      for (j = 0; j < n; j++) printf ("%8.4f", a[i][j]);
      printf (" | %8.4f\n", b[i]);
   }
}

/* Решение системы n линейных уравнений с n неизвестными.
   a - матрица коэффициентов;
   b - правые части;
   x - массив, куда нужно поместить решение.
   Функция возвращает значение 1, если систему удалось решить,
   и 0, если матрица коэффициентов оказалась особенной.
*/
double modul (double f)
{
	if (f<0) f=-f;
	return f;
}
///////////////////////////////////////////////////////////////////////////////////////
double gauss (double a[][10], double b[], double x[], int n)
{
double line[10], last;
int i, j, k, istek, defin;
double stek, c;
for (k=0; k<n; k++)
	{
	j=k;
	stek=0;
	istek=k;
//выбор макс. э-та столбца
	for (i=k; i<n; i++)
		{
		if (modul(a[i][j])>stek)
			{
			istek=i;
			stek=modul(a[i][j]);
			}
		}
if (stek==0) defin=0;
	for (j=0; j<n; j++)
		{
		line[j]=a[istek][j];
		a[istek][j]=a[k][j];
		a[k][j]=line[j];
		}
	last=b[istek];
	b[istek]=b[k];
	b[k]=last;

//делаем нули под главной диагональю
	for (i=(k+1); i<n; i++)
		{
		c=(a[i][k]/a[k][k]);
		for (j=0; j<n; j++)
			{
			a[i][j]=(a[i][j]-a[k][j]*c);
			};
		b[i]=(b[i]-b[k]*c);
		}
	}
for (i=(n-1); i>-1; i--)
	{
	x[i]=b[i];
	for (j=n; j>i; j--)
		{
		x[i]-=(a[i][j]*x[j]);
		}
	x[i]/=a[i][i];
	}
return x[n];
}
////////////////////////////////////////////////////////////////////////////////////
int linsys (int n, double a[][10], double b[], double x[])
{
int defin;
if (defin!=0||a[n][n]!=0)
   return 1;
if (a[n][n]==0)return 0;
}

void main()
{
   static double a[10][10], b[10];
   double x[10];
   int i, n, j;

   if ((n = getdata (a, b)) == 0) exit (1);

   printdata (n, a, b);
  // ________________________
   gauss (a, b, x, n);
   printf ("___________________________________\n");
   for (i=0; i<n; i++)
	{
	for (j=0; j<n; j++)
		{
		printf ("%8.4f", a[i][j]);
		};
	printf (" | %8.4f\t\n", b[i]);
	}

   //__________________________
   gauss (a, b, x, n);
   if (linsys (n, a, b, x)==1)
       for (i = 0; i < n; i++) printf ("x%d = %19.15f\n", i+1, x[i]);
   else
       printf ("Matrix is singular\n");

   exit (0);
}
