• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem z kompilacją kodu źródłowego.

Object Storage Arubacloud
0 głosów
212 wizyt
pytanie zadane 4 listopada 2019 w C i C++ przez Gw0zdziu09 Nowicjusz (180 p.)

Witam,

Napisałem program rozwiązujący algorytm węgierski. Przy kompilacji wywala ten sam błąd w trzech różnych miejscach.

#include <iostream>
#include <cstdlib>
#include <math.h>
#include <fstream>

using namespace std;

int main() {


	int x = 0;
	while (x > 3 || x < 1)
	{
		cout << "*******************MENU********************" << endl;
		cout << "1.Podawanie losowych wartosci nxn tablicy" << endl;
		cout << "2.Podawanie w³asnych wartosci do tablicy" << endl;
		cout << "3.Wczytanie macierzy z pliku" << endl;
		cout << "Wybieram : ";
		cin >> x;
		system("cls");
	}

	switch (x)
	{
	case 1:
	{
		//podanie wielkość macierzy
		int n, x, y = 0;
		cout << "podaj wielkosc" << endl;
		cin >> n;
		cout << "podaj zakres poczatkowy" << endl;
		cin >> x;
		cout << "podaj zakres koncowy" << endl;
		cin >> y;
		cout << endl;

		int tab[n][n];

		// wczytywanie danych do tablicy
		for (int i = 0; i < n; i++) {


			for (int j = 0; j < n; j++)
			{
				tab[i][j] = rand() % (y - x + 1) + x;


			}
		}

		// tworzenie pliku i sprawdzanie czy istnieje
		fstream tablica;
		string nazwapliku;
		cout << "Podaj nazwe pliku: ";
		cin >> nazwapliku;
		nazwapliku += ".txt";
		tablica.open(nazwapliku.c_str(), ios::out);

		if (!tablica.good())
		{
			cout << "Nie udalo sie utworzyc pliku!\n";
		}
		else
		{
			cout << "Plik został utworzony!\n";
		}

		// odczyt danych z tablicy
		for (int i = 0; i < n; i++) {

			for (int j = 0; j < n; j++)
			{
				cout << tab[i][j] << " ";
				tablica << tab[i][j] << " ";
			}
			tablica << endl;
			cout << endl;
		}
		tablica.close();
		cout << endl << endl;

		break;
	}

	case 2:
	{

		//tworzenie tablicy
		int n = 0;
		cout << "podaj wielkosc" << endl;
		cin >> n;
		int tab[n][n];


		// wczytywanie danych do tablicy
		for (int i = 0; i < n; i++) {


			for (int j = 0; j < n; j++)
			{
				cin >> tab[i][j];
			}
		}

		//tworzenie pliku i sprawdzanie i zapis
		fstream tablica;
		string nazwapliku;
		cout << "Podaj nazwe pliku: ";
		cin >> nazwapliku;
		nazwapliku += ".txt";
		tablica.open(nazwapliku.c_str(), ios::out);
		if (!tablica.good())
		{
			cout << "Nie udalo sie utworzyc pliku!\n";
		}
		else
		{
			cout << "Plik został utworzony!\n";
		}
		// odczyt danych z tablicy
		for (int i = 0; i < n; i++) {

			for (int j = 0; j < n; j++)
			{
				cout << tab[i][j] << " ";
				tablica << tab[i][j] << " ";
			}
			tablica << endl;
			cout << endl;
		}
		tablica.close();
		cout << endl << endl;


	}

	break;

	case 3:
	{

		//tworzenie tablicy
		int n = 0;
		cout << "podaj wielkosc" << endl;
		cin >> n;

		int tab[n][n];
		//wczytanie pliku i tablicy
		{
			ifstream plik1;
			string nazwapliku;
			cout << "Podaj nazwe pliku: ";
			cin >> nazwapliku;
			nazwapliku += ".txt";
			plik1.open(nazwapliku.c_str(), ios::in);
			if (plik1.good() == true)
			{
				for (int i = 0; i < n; i++)
				{
					for (int j = 0; j < n; j++)
					{
						plik1 >> tab[i][j];
					}

				}
			}
			plik1.close();


		}
		//wyswietlanie tablicy

		{ cout << "Tablica: " << endl << endl;
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
			{
				cout << tab[i][j] << " ";
			}
			cout << endl;
		}
		cout << endl;
		}

	}
	break;
	}


	system("PAUSE");
	return EXIT_SUCCESS;
}


Wywala takie błędy:

2 odpowiedzi

0 głosów
odpowiedź 4 listopada 2019 przez adrian17 Ekspert (345,220 p.)
int tab[n][n];

Przy takich tablicach, n musi być wartością stałą, znaną podczas kompilacji.

Musisz tą tablicę zaalokować dynamicznie (lub użyć std::vector).

komentarz 4 listopada 2019 przez Gw0zdziu09 Nowicjusz (180 p.)
Gdzie wpisać te std:vector?
komentarz 4 listopada 2019 przez adrian17 Ekspert (345,220 p.)
Nie będę od zera wyjaśniał jak się używa bibliotekę standardową ;) Radzę po prostu trochę poczytać o dynamicznej alokacji pamięci.
komentarz 5 listopada 2019 przez niezalogowany
przywrócone 5 listopada 2019

poczytać zawsze warto!

ale tu drobne oszustwo jakbyś nie chciał  przerabiać całego kodu

   { 
     int a;
    cin>>a;
    const int n=a;
    int tab[n][n];
}

 

https://stackoverflow.com/questions/2392655/what-are-the-signs-of-crosses-initialization

komentarz 5 listopada 2019 przez adrian17 Ekspert (345,220 p.)
edycja 5 listopada 2019 przez adrian17
Um, nie, to też nie zadziała, będzie ten sam błąd. Powtórzę: znaną podczas kompilacji. Tutaj wartość `n` nie jest znana przez kompilator.

(Link do StackOverflow nie ma też związku ani z pytaniem, ani z Twoją odpowiedzią. Nie dałeś przypadkiem złego linku?)
komentarz 5 listopada 2019 przez niezalogowany
edycja 5 listopada 2019

code::blocks

#include <iostream>

using namespace std;

int main() {


    int case_;
    cout<<"podaj nr:";
    cin>>case_;
    switch (case_) {

    case 1: {
        cout<<"podaj rozmiar tablicy:";
        int a;
        cin>>a;
        const int n=a;
        int tab[n][n];
        for(int j=0; j<n; j++)
            for(int i=0; i<n; i++){
                tab[i][j]=i*j;
                cout<<tab[i][j]<<' ';
            }
    }

    break;
    case 2: {
        cout<<"podaj rozmiar tablicy:";
        int a;
        cin>>a;
        const int n=a;
        int tab[n][n];
        for(int j=0; j<n; j++)
            for(int i=0; i<n; i++) {
                tab[i][j]=i+j;
                cout<<tab[i][j];
            }
    }
    break;
    default: {
        cout<<"podaj rozmiar tablicy:";
        int a;
        cin>>a;
        const int n=a;
        int tab[n][n];
        for(int j=0; j<n; j++)
            for(int i=0; i<n; i++)
                tab[i][j]=i*i;
    }
    break;
    }
    return 0;
}

wyjście

podaj nr:1
podaj rozmiar tablicy:4
0 0 0 0 0 1 2 3 0 2 4 6 0 3 6 9
Process returned 0 (0x0)   execution time : 5.000 s
Press any key to continue.

 Fakt 100 razy wolę std::vector, ale to 2 dni intensywnego rozkminiania (mi zajęło znaczne więcej aby się utrwalił) i żeby był użyteczny a nie tylko push_back i for (auto ..).

New też są problemy jak jest więcej niż jeden wymiar. I przy kompilacji i z destruktorem.

edit :: to też nie na temat ale może pomóc. https://www.modernescpp.com/index.php/c-core-guidelines-to-switch-or-not-to-switch-that-is-the-question

komentarz 5 listopada 2019 przez adrian17 Ekspert (345,220 p.)

code::blocks

Więc tutaj używasz rozszerzenia GCC - to nie jest legalny czysty C++. Jak w Code::Blocksie włączysz wyświetlanie więcej ostrzeżeń, to zobaczysz to:

<source>:18:13: warning: ISO C++ forbids variable length array 'tab' [-Wvla]
   18 |         int tab[n][n];
      |             ^~~

Autor pytania używa Visual Studio, który nie ma tego niestandardowego rozszerzenia języka.

komentarz 5 listopada 2019 przez adrian17 Ekspert (345,220 p.)

To jak to zrobić, żeby działało?

Można zastąpić dynamicznie alokowaną tablicą:

int **tab = new int*[n];
for (int i = 0; i < n; ++i)
	tab[i] = new int[n];

Tylko trzeba potem pamiętać o jej poprawnej dealokacji później.

Albo użyć std::vector, jak mówiłem wcześniej (choć jest to odrobinę brzydkie przy konstruowaniu 2D):

std::vector<std::vector<int>> tab(4, std::vector<int>(4));

 

komentarz 5 listopada 2019 przez niezalogowany
edycja 5 listopada 2019
Ok. Rzeczywiście może się nie potrzebnie odezwałem.

Std::vector to była słuszna podpowiedz.

edit:: k woli wyjaśnienia dlaczego c::b a nie visual.

1) Bo to na tym forum była dyskusja, ze visual coś dołącza od siebie biblioteki i częściej się kompiluje niż c::b (ale chyba coś nie do końca zrozumiałem), ale nie miałem pojęcia, że c::b nie jest zgodny ze standardem ISO.

2) Sprzęt mi na to tylko pozwala, jak za duże środowisko, lub zanieczyszczony to nie da się nic zrobić.
komentarz 5 listopada 2019 przez adrian17 Ekspert (345,220 p.)

ale nie miałem pojęcia, że c::b nie jest zgodny ze standardem ISO.

W praktyce wszystkie kompilatory dodają jakieś rzeczy od siebie - jedne opt-in, inne opt-out ;) MSVC też ma swoje śmieszne rzeczy które nie zadziałają na GCC.

(najnowszy VS2019 jest zauważalnie lżejszy btw)

komentarz 5 listopada 2019 przez niezalogowany
ok. Dzięki z info.
0 głosów
odpowiedź 5 listopada 2019 przez Gw0zdziu09 Nowicjusz (180 p.)
To jak to zrobić, żeby działało?
komentarz 5 listopada 2019 przez niezalogowany

u mnie nawet to działa

#include <iostream>
#include <cstdlib>
#include <math.h>


using namespace std;

int main() {


    int x = 0;
    while (x > 3 || x < 1)
    {
        cout << "*******************MENU********************" << endl;
        cout << "1.Podawanie losowych wartosci nxn tablicy" << endl;
        cout << "2.Podawanie w³asnych wartosci do tablicy" << endl;
        cout << "3.Wczytanie macierzy z pliku" << endl;
        cout << "Wybieram : ";
        cin >> x;
        system("cls");
    }

    switch (x)
    {
    case 1:
    {
        //podanie wielkość macierzy
        int n, x, y = 0;
        cout << "podaj wielkosc" << endl;
        cin >> n;
        cout << "podaj zakres poczatkowy" << endl;
        cin >> x;
        cout << "podaj zakres koncowy" << endl;
        cin >> y;
        cout << endl;

        int tab[n][n];

        // wczytywanie danych do tablicy
        for (int i = 0; i < n; i++) {


            for (int j = 0; j < n; j++)
            {
                tab[i][j] = rand() % (y - x + 1) + x;
            }
        }


        for (int i = 0; i < n; i++) {

            for (int j = 0; j < n; j++)
            {
                cout << tab[i][j] << " ";

            }

            cout << endl;
        }
        cout << endl << endl;

        break;
    }
    default:
        cout<<endl<<"podano inną cyfrę niż 1"<<endl;
    }
    return 0;
}
podaj wielkosc
2
podaj zakres poczatkowy
2
podaj zakres koncowy
7

7 7
6 6



Process returned 0 (0x0)   execution time : 19.703 s
Press any key to continue.

 

komentarz 5 listopada 2019 przez tkz Nałogowiec (42,000 p.)

Działa bo kompilator rozszerza możliwości standardu, dodając tworzenie tablic typu VLA. 

https://wandbox.org/permlink/aSlIhOXDNCJnGjHc spójrz na listę błędów. 

komentarz 5 listopada 2019 przez niezalogowany
Rzeczywiście(2), ale napisałem że to drobne oszustwo i kompilator puszcza. Ale nie napisałem ze to poprawne rozwiązanie. Zawsze można zarezerwować dużo większą tablicę. Ale operatorem new to też trzeba umieć wskaźniki, i wskaźniki na  wskaźnik. No i odpowiednio jeszcze to poczyścić.

Tu na forum był fajny przykład ale nie mogę zanieść by nie pisać od początku. Rezerwacji i zwalniania operatorem new.

Tu jest chyba też przyzwoicie zrobione https://eduinf.waw.pl/inf/alg/001_search/0074.php

Podobne pytania

0 głosów
1 odpowiedź 407 wizyt
pytanie zadane 19 lutego 2020 w Mikrokontrolery przez Mavimix Dyskutant (8,390 p.)
+1 głos
1 odpowiedź 207 wizyt
pytanie zadane 11 kwietnia 2021 w C i C++ przez Dawidziu Bywalec (2,610 p.)
0 głosów
1 odpowiedź 510 wizyt
pytanie zadane 8 kwietnia 2021 w C i C++ przez Dawidziu Bywalec (2,610 p.)

92,634 zapytań

141,505 odpowiedzi

319,883 komentarzy

62,015 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...