Liczenie wyznacznika macierzy wczytywanej z pliku txt. Język C.

0

Napisac w jezyku C program obliczajacy wyznacznik macierzy
o dowolnym rozmiarze. Macierz powinna byc wczytywana z pliku tekstowego.

Treść rozumiem bardzo dobrze. Nie umiem jedynie przełożyć tego na język C.
Mianowicie chcę stworzyć sobie dwie tablice:

  • pierwsza to tablica wskaźników na pierwsze elementy każdego wiersza macierzy
  • druga to tablica zawierająca wszystkie elementy macierzy

plik tekstowy wygląda np. tak:

3
1 2 3
4 5 6
7 8 9 

Przy czym cyfra na samej górze to rozmiar macierzy, a pozostałe cyfry to jej elementy.

Jestem głupi. Tzn. nie w sensie dosłownym, tylko nie umiem sprawnie programować, brak mi narzędzi żeby przelać dany pomysł na kod.
Myślę, że z policzeniem wyznacznika dam sobie radę, natomiast mam problem ze skopiowaniem fscanf'em danych z pliku do programu.

Kod na razie wygląda tak:

#include <stdio.h>
#include <stdlib.h>

int czytajZPliku();
void stworzTabliceWsk(double tab_wsk, int rozmiar);
double liczWyznacznik();


int main(){
    int rozmiar_macierzy = czytajZPliku();
	printf("\nRozmiar macierzy wczytanej z pliku to: %d\n", rozmiar_macierzy);
    
	double *tab_wsk = (double*)malloc(sizeof(double) * rozmiar_macierzy);
	stworzTabliceWsk(*tab_wsk, rozmiar_macierzy);

    /*printf("Wyznacznik tej macierzy to: %lf", liczWyznacznik());*/

	free (tab_wsk);
    printf("\n\n");
	system("PAUSE");
    return 0;
}

int czytajZPliku(){
    
    int rozmiar = 0;
	
    FILE *plik;
      plik = fopen ("macierz.txt","r");
      if (plik!=NULL){
        fscanf(plik, "%d", &rozmiar);
		fclose(plik);
		return rozmiar;
      }
      
    else {
        printf("Plik tekstowy jest nieprawdlowy.\n");
		return 0;
        }
}

void stworzTabliceWsk(double tab_wsk, int rozmiar){
	int i = 0;
	FILE *plik;
      plik = fopen ("macierz.txt","r");
      if (plik!=NULL){
    

		fclose(plik);
		
      }
      
    else {
        printf("Plik tekstowy jest nieprawdlowy.\n");
		exit(1);
        }

}
double liczWyznacznik(){
	double wynik = 0;
	/* ... */
	return wynik;
} 

Nie kompiluje się.

Komunikaty od Visual C++:

 1>------ Build started: Project: Wyznacznik, Configuration: Release Win32 ------
1>  wyznacznik.c
1>wyznacznik.c(17): error C2143: syntax error : missing ';' before 'type'
1>wyznacznik.c(18): error C2065: 'tab_wsk' : undeclared identifier
1>wyznacznik.c(18): error C2100: illegal indirection
1>wyznacznik.c(22): error C2065: 'tab_wsk' : undeclared identifier
1>wyznacznik.c(22): warning C4022: 'free' : pointer mismatch for actual parameter 1
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

To są błędy ze wskaźnikami i przekazywaniem argumentów do funkcji. Wynikają mojego z braku praktycznej wiedzy. Przepraszam za nie. Będę próbował to poprawić.

Liczę na jakieś naprowadzenie mnie. Nie do końca wiem jak zrobić żeby np. fscanf pominął '3' przy wypelnianiu tablicy ale pozostale liczby sobie ladnie wpisal.

Ostatnim razem pomogliście mi w pół godziny. Byłem w lekkim szoku, ale tamten program był prostszy.
Będę wdzięczny za wszelkie pomysły, wskazówki;)
Pozdrawiam

0

na początek poczytaj o pętlach i tablicach dwuwymiarowych

1

https://ideone.com/KcHN1E

Nie trzeba tworzyć dwuwymiarowej tablicy, a raczej tablicy wskaźników na kolejne wiersze, bo wszystkie wiersze i tak mają tą samą wielkość. Korzystając z tego faktu można stworzyć jedną, ciągłą tablicę i trzymać w niej elementy liniowo. Jak pokazane w drugiej pętli, gdzie elementy są wypisywane, dostęp do poszczególnych komórek jest prosty: i * matrix_size + j.

#include <stdlib.h>
#include <stdio.h>

int main()
{
    size_t matrix_size, array_size;
    int *matrix, i, j;

    FILE *file = fopen("data.txt", "r");
    fscanf(file, "%d", &matrix_size);
    array_size = matrix_size * matrix_size;
    
    matrix = (int*)malloc(sizeof(*matrix) * array_size);
    
    for(i = 0; i < array_size; i++)
        fscanf(file, "%d", &matrix[i]);

    fclose(file);

    for(i = 0; i < matrix_size; i++)
    {
        for(j = 0; j < matrix_size; j++)
            printf("%d ", matrix[i * matrix_size + j]);

        printf("\n");
    }

    free(matrix);

    return 0;
}
0

Dostosowałem kod od Rev do swojego programu i niestety wystąpiła masa błędów, które są dla mnie niezrozumiałe. Np. kompilator chce, spodziewa się średnika tam, gdzie go nie może być. Na pewno są tu jakieś wielkie przestępstwa popełnione ale ja nie potrafię sam ich zdiagnozować.
Będę jeszcze kombinował, ale nie mam za dużo czasu dlatego wrzucę kod to może wy coś wyszukacie.

/*Napisac w jezyku C program obliczajacy wyznacznik macierzy 
o dowolnym rozmiarze. Macierz powinna byc wczytywana z pliku tekstowego
*/

#include <stdio.h>
#include <stdlib.h>

int czytajZPliku();
double liczWyznacznik();


int main(){
    double *matrix;
	int i, j;
	int rozmiar_macierzy = czytajZPliku();
	printf("\nRozmiar macierzy wczytanej z pliku to: %d\n", rozmiar_macierzy);
	
	int array_size;
   
 
    FILE *plik;
      plik = fopen("macierz.txt","r");
      if (plik!=NULL){
		array_size = rozmiar_macierzy * rozmiar_macierzy;
    
		matrix = (double*)malloc(sizeof(*matrix) * array_size);
    
		for(i = 0; i < array_size; i++)
        fscanf(plik, "%d", &matrix[i]);
 
		fclose(plik);
		}
	  else {
        printf("Plik tekstowy jest nieprawdlowy.\n");
		fclose(plik);
		exit(1);
        }
    
 
    for(i = 0; i < rozmiar_macierzy; i++)
    {
        for(j = 0; j < rozmiar_macierzy; j++)
			printf("%d ", matrix[i * rozmiar_macierzy + j]);
 
        printf("\n");
    }
 
    free(matrix);

    /*printf("Wyznacznik tej macierzy to: %lf", liczWyznacznik());*/

	
    printf("\n\n");
	system("PAUSE");
    return 0;
}

int czytajZPliku(){
    
    int rozmiar = 0;
	
    FILE *plik;
      plik = fopen("macierz.txt","r");
      if (plik!=NULL){
        fscanf(plik, "%d", &rozmiar);
		fclose(plik);
		return rozmiar;
      }
      
    else {
        printf("Plik tekstowy jest nieprawdlowy.\n");
		fclose(plik);
		return 0;
        }
}


double liczWyznacznik(){
	double wynik = 0;
	/* ... */
	return wynik;
} 

i komunikaty Visuala:

1>------ Build started: Project: Wyznacznik, Configuration: Release Win32 ------
1>  wyznacznik.c
1>wyznacznik.c(18): error C2143: syntax error : missing ';' before 'type'
1>wyznacznik.c(21): error C2275: 'FILE' : illegal use of this type as an expression
1>          D:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\stdio.h(66) : see declaration of 'FILE'
1>wyznacznik.c(21): error C2065: 'plik' : undeclared identifier
1>wyznacznik.c(23): error C2065: 'plik' : undeclared identifier
1>wyznacznik.c(23): warning C4047: '!=' : 'int' differs in levels of indirection from 'void *'
1>wyznacznik.c(24): error C2065: 'array_size' : undeclared identifier
1>wyznacznik.c(26): error C2065: 'array_size' : undeclared identifier
1>wyznacznik.c(28): error C2065: 'array_size' : undeclared identifier
1>wyznacznik.c(29): error C2065: 'plik' : undeclared identifier
1>wyznacznik.c(29): warning C4047: 'function' : 'FILE *' differs in levels of indirection from 'int'
1>wyznacznik.c(29): warning C4024: 'fscanf' : different types for formal and actual parameter 1
1>wyznacznik.c(31): error C2065: 'plik' : undeclared identifier
1>wyznacznik.c(31): warning C4047: 'function' : 'FILE *' differs in levels of indirection from 'int'
1>wyznacznik.c(31): warning C4024: 'fclose' : different types for formal and actual parameter 1
1>wyznacznik.c(35): error C2065: 'plik' : undeclared identifier
1>wyznacznik.c(35): warning C4047: 'function' : 'FILE *' differs in levels of indirection from 'int'
1>wyznacznik.c(35): warning C4024: 'fclose' : different types for formal and actual parameter 1
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

Jakbym jeszcze z dwa tygodnie nad tym posiedział to może bym sobie poradził sam, ale mam czas do jutra:|

1

Visual nie lubi w C definicji zmiennych wewnątrz bloku. Przenieś zmienne na sam początek funkcji.

Dodatkowo, może ci pokażę wynik z innego kompilatora...

a.c:29:24: warning: format specifies type 'int *' but the argument has type 'double *' [-Wformat]
        fscanf(plik, "%d", &matrix[i]);
                      ~^   ~~~~~~~~~~
                      %lf
a.c:43:34: warning: format specifies type 'int' but the argument has type 'double' [-Wformat]
                        printf("%d ", matrix[i * rozmiar_macierzy + j]);
                                ~^    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                %f
2 warnings generated.
0
1>------ Build started: Project: Wyznacznik, Configuration: Release Win32 ------
1>  wyznacznik.c
1>wyznacznik.c(22): error C2275: 'FILE' : illegal use of this type as an expression
1>          D:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\stdio.h(66) : see declaration of 'FILE'
1>wyznacznik.c(22): error C2065: 'plik' : undeclared identifier
1>wyznacznik.c(23): error C2065: 'plik' : undeclared identifier
1>wyznacznik.c(23): warning C4047: '=' : 'int' differs in levels of indirection from 'FILE *'
1>wyznacznik.c(24): error C2065: 'plik' : undeclared identifier
1>wyznacznik.c(24): warning C4047: '!=' : 'int' differs in levels of indirection from 'void *'
1>wyznacznik.c(30): error C2065: 'plik' : undeclared identifier
1>wyznacznik.c(30): warning C4047: 'function' : 'FILE *' differs in levels of indirection from 'int'
1>wyznacznik.c(30): warning C4024: 'fscanf' : different types for formal and actual parameter 1
1>wyznacznik.c(32): error C2065: 'plik' : undeclared identifier
1>wyznacznik.c(32): warning C4047: 'function' : 'FILE *' differs in levels of indirection from 'int'
1>wyznacznik.c(32): warning C4024: 'fclose' : different types for formal and actual parameter 1
1>wyznacznik.c(36): error C2065: 'plik' : undeclared identifier
1>wyznacznik.c(36): warning C4047: 'function' : 'FILE *' differs in levels of indirection from 'int'
1>wyznacznik.c(36): warning C4024: 'fclose' : different types for formal and actual parameter 1
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

poprawiłem te &d na &lf

a o co chodzi z tymi "error C2065: 'plik' : undeclared identifier"?

1

O to, że parser się pogubił i po pierwszym błędzie dalej już wali śmieci. Nie przeniosłeś zmiennych na początek.

0

Wszystkie zmienne mam na samym początku każdej funkcji i nadal mam te same błędy.

/*Napisac w jezyku C program obliczajacy wyznacznik macierzy 
o dowolnym rozmiarze. Macierz powinna byc wczytywana z pliku tekstowego
*/

#include <stdio.h>
#include <stdlib.h>

int czytajZPliku();
double liczWyznacznik();


int main(){
    double *matrix;
	int i, j;
	int rozmiar_macierzy;
	int array_size;
	rozmiar_macierzy = czytajZPliku();
	
	printf("\nRozmiar macierzy wczytanej z pliku to: %d\n", rozmiar_macierzy);
	
	
   
 
    FILE *plik;
      plik = fopen("macierz.txt","r");
      if (plik!=NULL){
		array_size = rozmiar_macierzy * rozmiar_macierzy;
    
		matrix = (double*)malloc(sizeof(*matrix) * array_size);
    
		for(i = 0; i < array_size; i++)
        fscanf(plik, "%lf", &matrix[i]);
 
		fclose(plik);
		}
	  else {
        printf("Plik tekstowy jest nieprawdlowy.\n");
		fclose(plik);
		exit(1);
        }
    
 
    for(i = 0; i < rozmiar_macierzy; i++)
    {
        for(j = 0; j < rozmiar_macierzy; j++)
			printf("%lf ", matrix[i * rozmiar_macierzy + j]);
 
        printf("\n");
    }
 
    free(matrix);

    /*printf("Wyznacznik tej macierzy to: %lf", liczWyznacznik());*/

	
    printf("\n\n");
	system("PAUSE");
    return 0;
}

int czytajZPliku(){
    
    int rozmiar = 0;
	
    FILE *plik;
      plik = fopen("macierz.txt","r");
      if (plik!=NULL){
        fscanf(plik, "%d", &rozmiar);
		fclose(plik);
		return rozmiar;
      }
      
    else {
        printf("Plik tekstowy jest nieprawdlowy.\n");
		fclose(plik);
		return 0;
        }
}


double liczWyznacznik(){
	double wynik = 0;
	/* ... */
	return wynik;
} 

Jest tu jakaś nieprzeniesiona zmienna? Wg. mnie nie ma.

0

FILE *plik;

Albo zamień po prostu rozszerzenie na .cpp i w myślach sobie udawaj, że to C99.

1 użytkowników online, w tym zalogowanych: 0, gości: 1