[C/C++]Błąd podczas kompilacji

Witam.

Mam taki mały problem.

Chcę stworzyć plik binarny o nazwie podanej z klawiatury.

Zadeklarowałem sobie char f[20], który ma przechowywać właśnie tą nazwę.

FILE* plik=fopen("f", "wb");

fwrite(&tab, sizeof(Osoba), i, "f");


fclose("f");

W tym kodzie wyskakuje mi błąd:

test.cxx:88:26: error: cannot convert ‘std::string {aka std::basic_string}’ to ‘const char*’ for argument ‘1’ to ‘FILE* fopen(const char*, const char*)’

test.cxx:89:36: error: cannot convert ‘const char*’ to ‘FILE* {aka _iobuf*}’ for argument ‘4’ to ‘size_t fwrite(const void*, size_t, size_t, FILE*)’

test.cxx:91:10: error: cannot convert ‘std::string {aka std::basic_string}’ to ‘FILE* {aka _iobuf*}’ for argument ‘1’ to ‘int fclose(FILE*)’

test.cxx:88:8: warning: unused variable ‘plik’ [-Wunused-variable]

Kompilacja nie powiodła się

Nie mam pojęcia co dalej z tym robić. Wydaje się, że coś źle wpisuję jako nazwę pliku. Tylko jak to poprawić?

Dzięki.

Skoro f jest char[], to czemu jako pierwszy argument podajesz "f"? W ten sposób przekazujesz ciąg znaków, czyli tekst (stały literał) "f" zamiast ciąg z tablicyf.

test.cxx:88:26: error: cannot convert 'std::string {aka std::basic_string}' to 'const char*' for argument '1' to 'FILE* fopen(const char*, const char*)'

std::string to nie (const) char*. Możesz wyciągnąć ciąg w postaci char* poprzez metodę (std::string).c_str()

test.cxx:89:36: error: cannot convert 'const char*' to 'FILE* {aka _iobuf*}' for argument '4' to 'size_t fwrite(const void*, size_t, size_t, FILE*)'

Za 4 argument podajesz wskaźnik (uchwyt) do pliku, a nie jego nazwę, znów podana nieprawidłowo, bo przez gotowy ciąg znaków zamiast wyciągnięcie go z tablicy. Wskaźnikiem na plik jest zmienna (wkaźnik) `plik u ciebie.

test.cxx:91:10: error: cannot convert 'std::string {aka std::basic_string}' to 'FILE* {aka _iobuf*}' for argument '1' to 'int fclose(FILE*)'

Znów w fclose używasz stałego literału. Przekazujesz tam wskaźnik do pliku, nie jego nazwę.

test.cxx:88:8: warning: unused variable 'plik' [-Wunused-variable]

Ostrzeżenie o nieużywanym pliku.

Popatrzyłem, poczytałem, zrozumiałem. A oto poprawiony fragment. Kompilator już się nie drze.

FILE* plik=fopen(f, "wb");

fwrite(&tab, sizeof(Osoba), i, plik);


fclose(plik);

Dzięki za wytłumaczenie. Mam jeszcze jeden malutki problemik. Otóż mam: char klucz[9]; //na tej tablicy będzie nazwisko, wzrost lub wiek Chcę porównać to co znajduje się pod kluczem z wyrazami nazwisko, wiek i wzrost. Napisałem:

if(klucz == 'nazwisko')

I dostaję:

warning: character constant too long for its type [enabled by default]

To samo z wiekiem i wzrostem. Czy ja dobrze zapisuję to porównanie?

//Rozwiązałem ten problem za pomocą strcmp.

Nie. Apostrofy pojedyncze ’ służą do pisania pojedynczych znaków ((typ char), a " do słów (typ const char*, lub char*). Operator == porównuje obiekty, jeśli chcesz porównać char* z innym char*, operator == sprawdzi jedynie czy te 2 łańcuchy leżą w tym samym miejscu w pamięci.

Do ich porównania musisz użyć funkcji strcmp(const char*, const char*), kolejność argumentów dowolna.

Funkcja zwraca 0 jeśli oba ciągi są identyczne, lub liczbę większą od zera, gdy są różne (liczba to indeks pierwszych różniących się znaków)

Powstał jeszcze jeden problem.

Mam funkcję, która poszukuje elementów spełniających dane warunki, a potem wyświetla je na ekranie. Dostaje ona: nazwę pliku, z którego ma czytać elementy, dany warunek nazwisko, warunek wiek, warunek wzrost1 i wzrost2(rekordy mieszczące się między nimi są wypisywane). Jeżeli warunki nazwisko i/lub wiek dostaną wartość 0 to wyłączamy odpowiedni filtr.

Ona wczytuje do tablicy dane z pliku, po czym porównuje warunki(podane nazwisko lub/i podany wiek i podany wzrost) z elementami (elementami są struktury osoba: nazwisko, wiek, wzrost).

Niestety nie wiem co jest nie tak, ale funkcja nie wyświetla niczego, tak jakby się nie wykonała wcale, a menu programu wyświetla się ponownie.

Oto samo porównywanie:

if(nazwisko != 0 && wiek != 0)

	{

		for(int j=0;j
		{

			if(!strcmp(tab[j].nazwisko,nazwisko) && tab[j].wiek == wiek && tab[j].wzrost >= wzrost1 && tab[j].wzrost <= wzrost2)

			{

				printf("%s %d %f", tab[j].nazwisko, tab[j].wiek, tab[j].wzrost);

			}

		}

	} else if(nazwisko == 0 && wiek != 0) {

		for(int j=0;j
		{

			if(tab[j].wiek == wiek && tab[j].wzrost >= wzrost1 && tab[j].wzrost <= wzrost2)

			{

				printf("%s %d %f", tab[j].nazwisko, tab[j].wiek, tab[j].wzrost);

			}

		}

	} else if(nazwisko != 0 && wiek == 0) {

		for(int j=0;j
		{

			if(tab[j].nazwisko == nazwisko && tab[j].wzrost >= wzrost1 && tab[j].wzrost <= wzrost2)

			{

				printf("%s %d %f", tab[j].nazwisko, tab[j].wiek, tab[j].wzrost);

			}

		}

	} else if(nazwisko == 0 && wiek == 0) {

		for(int j=0;j
		{

			if(tab[j].wzrost >= wzrost1 && tab[j].wzrost <= wzrost2)

			{

				printf("%s %d %f", tab[j].nazwisko, tab[j].wiek, tab[j].wzrost);

			}

		}

	}

Żadnych błędów podczas kompilacji, czyli to sama koncepcja nie jest poprawna.

Dzięki.

Czy dane w ogóle się poprawnie wczytują?

Nie bój się używać printfów wszędzie gdzie się da by się tylko dowiedzieć czy dane fragment kodu jest wykonywany i jakie zmienne mają wartości.

Jeśli zmienna nazwisko jest char*, to porównując ją do 0 sprawdzasz, czy został podany NULL.

Sprawdziłem przed chwilą i:

w if’ach gdzie mam nazwisko != 0, operacje wykonują się i działają poprawnie. Pozostały tylko 2 if’y gdzie nazwisko porównuje do zera i wiek jest niezerowy oraz wiek jest także zerem.

Sprawdziłem printf’ami jakie pobieram dane - są one poprawne.

Będę cały czas testował kod, jakby ktoś coś zauważył w kodzie nie tak to proszę o podpowiedź.

//Edit: Okazało się, że problem rozwiązać można za pomocą funkcji strcmp(). Dzięki.