[C++] Wyznaczanie częstotliwości znaków

Transatlantyk
Użytkownik
Użytkownik
Posty: 52
Rejestracja: 30 cze 2014, o 15:08
Płeć: Kobieta
Lokalizacja: Ziemia

[C++] Wyznaczanie częstotliwości znaków

Post autor: Transatlantyk »

Napisać plik do wyznaczania częstotliwości występowania znaków i dwuznaków w pliku o podanej
nazwie. Plik jest zapisany alfabetem łacińskim (bez znaków diakrytyzowanych). Program wczytuje nazwę
pliku z linii poleceń (po przełączniku -i) i zapisuje wynik do pliku, którego nazwa jest podana po przełączniku -o. Przykładowe wywołanie programu:

Kod: Zaznacz cały

program.exe -o wyjscie -i wejscie

Kod: Zaznacz cały

#include "stdafx.h"
#include<iostream>
#include<fstream>
#include<string>

using namespace std;

/*skrót działania:
funkcja odczytująca pliki odczytu i zapisu
funkcja sprawdzająca poprawność wczytanych plików i zwracająca iformację
funkacja licząca dwuznaki w danym pliku
funkcja zapisaująca dane do pliku końcowego*/

string input(string tabk[1][2])
{
	string pliko, plikz;
	cout << "-o  "; cin >> plikz; cout << endl;
	cout << "-1  "; cin >> pliko; cout << endl;

	string tabk[1][2] = { "pliko", "plikz" };
	 
	return tabk[1][2];
}

string check(string & pliko, string & plikz, fstream &plik)
{
	bool p1=0, p2=0;
	fstream plik;
	void open (const char*plik, ios_base::openmode in);
	plik.open("pliko", ios::in);
	if (plik.good() == true) { p1 == 1; }
	plik.close();
	void open(const char*plik, ios_base::openmode out);
	plik.open("plikz", ios::out);
	if (plik.good() == true) { p2 == 1; }
	plik.close();

	if (p1 == 0) { cout << "Plik zapisu nie istnieje, spóbój jeszcze raz" << endl; cout << "-o  "; cin >> pliko; check( & pliko, & plikz); }
	if (p2 == 0) {cout << "Plik odczytu nie istnieje, spóbój jeszcze raz" << endl; cout << "-1  "; cin >> pliko;  check( & pliko, s& plikz);}
	return "pliko", "plikz";
}

double search()
{
	double dw = 0;
	double result1, result2;
	fstream plik("plikz", std::ios::in);
	string dane;
	getline(plik, dane);
	char y = dane.length();
	y = result1;
	char d = y, z = 0;
	char tab[100000000000];
	char tab2[100000000000];
	for (int j = 0; j < d; j++)
	{
		for (int i = 0; i < d; i++)
		{
			tab[j] = dane[z];
			tab2[i] = dane[z - 1];

			if (dane[z - 1] == "c")
			{
				if (dane[z] == "") { dw++; }
				if (dane[z] == "k") { dw++; }
				if (dane[z] == "s") { dw++; }
				if (dane[z] == "z") { dw++; }
				if (dane[z] == "i") { dw++; }
			}
			if (dane[z - 1] == "d")
			{
				if (dane[z] == "z") { dw++; }
				if (dane[z] == "ż") { dw++; }
				if (dane[z] == "ź") { dw++; }
				if (dane[z] == "z") { dw++; }
				if (dane[z] == "z"& dane[z + 1] == "i") { dw++; }
			}
			if (dane[z - 1] == "g")
			{
				if (dane[z] == "l") { dw++; }
				if (dane[z] == "h") { dw++; }
			}
			if (dane[z - 1] == "l") { if (dane[z] == "y") { dw++; } }

			if (dane[z - 1] == "p") { if (dane[z] == "h") { dw++; } }

			if (dane[z - 1] == "q") { if (dane[z] == "u") { dw++; } }

			if (dane[z - 1] == "t") { if (dane[z] == "h") { dw++; } }

			if (dane[z - 1] == "x") { if (dane[z] == "h") { dw++; } }

			if (dane[z - 1] == "c") { if (dane[z] == "i") { dw++; } }

			if (dane[z - 1] == "n")
			{
				if (dane[z] == "g") { dw++; }
				if (dane[z] == "y") { dw++; }
				if (dane[z] == "i") { dw++; }
			}
			if (dane[z - 1] == "n")
			{
				if (dane[z] == "g") { dw++; }
				if (dane[z] == "y") { dw++; }
			}
			if (dane[z - 1] == "s")
			{
				if (dane[z] == "h") { dw++; }
				if (dane[z] == "c") { dw++; }
				if (dane[z] == "z") { dw++; }
				if (dane[z] == "i") { dw++; }
			}
			if (dane[z - 1] == "z")
			{
				if (dane[z] == "h") { dw++; }
				if (dane[z] == "s") { dw++; }
				if (dane[z] == "i") { dw++; }
			}
			if (dane[z - 1] == "r")
			{
				if (dane[z] == "z") { dw++; }
			}

		}
		z++;
	}
	double tab3[2] = { result1, dw };

	return tab3[2];
}



int main()
{
	string tabk[1][2], pliko, plikz;
	fstream plik;
	input(tabk[1][2]);
	tabk[1] = pliko;
	tabk[2] = plikz;
	check( pliko, plikz, plik);
	search();
	
}
otóż taki kod stworzyłam
błędy, co do których przeszukałam całe google brzmią następująco:

Kod: Zaznacz cały

Error	C2446	'==': no conversion from 'const char *' to 'int'	

Error	C2664	'std::string input(std::string [][2])': cannot convert argument 1 from 'std::string' to 'std::string [][2]'	

Error (active)		initial value of reference to non-const must be an lvalue	
	
Error (active)		too few arguments in function call	

Error (active)		operand types are incompatible ("char" and "const char *")	

Error (active)		no suitable conversion function from "std::string" to "std::string (*)[2]" exists		

Error	C2082	redefinition of formal parameter 'tabk'	Projekt1	

Error	C2660	'check': function does not take 2 arguments	

Error	C2660	'check': function does not take 1 arguments	

Warning	C4267	'initializing': conversion from 'size_t' to 'char', possible loss of data		

Warning	C4244	'=': conversion from 'double' to 'char', possible loss of data

Error	C2446	'==': no conversion from 'const char *' to 'int'	

Warning	C4554	'&': check operator precedence for possible error; use parentheses to clarify precedence	

Poza oczywiście resztą, która wychodziprzy debuggowaniu, ale których nie miałam jeszcze jak poprawić

Serdecznie proszę mnie poprawić i oświecić
Ostatnio zmieniony 15 lis 2016, o 12:00 przez Afish, łącznie zmieniany 1 raz.
Powód: Poprawa wiadomości.
Gouranga
Użytkownik
Użytkownik
Posty: 1592
Rejestracja: 16 maja 2013, o 17:56
Płeć: Mężczyzna
Lokalizacja: Trójmiasto
Podziękował: 11 razy
Pomógł: 246 razy

[C++] Wyznaczanie częstotliwości znaków

Post autor: Gouranga »

W samej treści błędów jest jasno napisane co jest źle, choćby pierwszy, który mówi, że operator == nie wspiera konwersji z typu wskaźnika na znak do typu int. Taka wskazówka ode mnie: czytaj błędy.
kalwi
Użytkownik
Użytkownik
Posty: 1931
Rejestracja: 29 maja 2009, o 11:58
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 145 razy
Pomógł: 320 razy

[C++] Wyznaczanie częstotliwości znaków

Post autor: kalwi »

1)

Kod: Zaznacz cały

   string tabk[1][2], pliko, plikz;
   input(tabk[1][2]);
   tabk[1] = pliko;
   tabk[2] = plikz;

Nie umiesz korzystać z tablic

2)

Kod: Zaznacz cały

 Przykładowe wywołanie programu:
program.exe -o wyjscie -i wejscie

 string input(string tabk[1][2])
{
   string pliko, plikz;
   cout << "-o  "; cin >> plikz; cout << endl;
   cout << "-1  "; cin >> pliko; cout << endl;

   string tabk[1][2] = { "pliko", "plikz" };
    
   return tabk[1][2];
}
Wiesz co to jest linia poleceń? Raczej nie

3)

Kod: Zaznacz cały

   input(tabk[1][2]);

Kod: Zaznacz cały

   ...
return tabk[1][2];
}
Posługiwać się funkcjami też nie umiesz. O pisaniu prototypów funkcji już nie wspominając.

Kod: Zaznacz cały

    string tabk[1][2] = { "pliko", "plikz" };
   return tabk[1][2];
Zasięg życia zmiennych się kłania

4)

Kod: Zaznacz cały

string check(string & pliko, string & plikz, fstream &plik)
I dalej

Kod: Zaznacz cały

   fstream plik;
Bez sensu.

5)

Kod: Zaznacz cały

   bool p1=0, p2=0;
bool jest typu true lub false, nie 0 lub 1

6)

Kod: Zaznacz cały

   char y = dane.length();
do typu char chcesz przypisać coś typu size_t

Kod: Zaznacz cały

   double result1, result2;
   y = result1;
...a następnie tę wartość zastąpić jakąś wartością randomową z pamięci

7)

Kod: Zaznacz cały

   char tab[100000000000];
   char tab2[100000000000];
Potem elegancko zajmujesz ~180GB pamięci

Kod: Zaznacz cały

   for (int j = 0; j < d; j++)
Następnie porównujesz char z intem

8)

Kod: Zaznacz cały

 dw++;
Potem nie wiedzieć czemu robisz inkrementację na typie double zamiast na size_t albo int

9)

Kod: Zaznacz cały

            if (dane[z] == "h") { dw++; }
            if (dane[z] == "c") { dw++; }
o else if też nie słyszałaś

10)

Kod: Zaznacz cały

 double tab3[2] = { result1, dw };
   return tab3[2];
Następnie to znowu nie działa tak jak myślisz

inne błędy też są, ale już nawet nie chce mi się ich wypisywać. Naucz się podstaw zanim przejdziesz do ambitniejszych rzeczy. I jak wypisujesz to co wyskoczyło w błędach - to skopiuj to razem z linijkami.
Transatlantyk
Użytkownik
Użytkownik
Posty: 52
Rejestracja: 30 cze 2014, o 15:08
Płeć: Kobieta
Lokalizacja: Ziemia

[C++] Wyznaczanie częstotliwości znaków

Post autor: Transatlantyk »

Dzięki za odpowiedzi, choć poczułam się po nich jak ostatni łoś. Biorę się za coś ambitniejszego ponieważ taki mam projekt na sttudiach, na pierwszym roku. Dla niektórych to banał, ale ja nie mam żadnych podstaw i użycia funkcji id uczę się właśnie teraz, popierając się google, nie mam skąd zasięgnąć więcej informacji, dlatego działanie programu w wielu wierszach jest dla mnie trudne do zrozumoenia(każdy wie, że logika programowania jest tak prosta, że aż zbyt trudna do odkrycia).
kalwi
Użytkownik
Użytkownik
Posty: 1931
Rejestracja: 29 maja 2009, o 11:58
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 145 razy
Pomógł: 320 razy

[C++] Wyznaczanie częstotliwości znaków

Post autor: kalwi »

My na PW na pierwszym semestrze również mieliśmy programowanie od zera (tj. zakładając, że wcześniej się nie programowało), w języku C. Projekty były takie:


Ja miałem ten ostatni, kod jest tu:


I cóż, trzeba się uczyć tak naprawdę patrząc na kod z wykładu i następnie go lekko modyfikować, aby orientować się co się wyrabia. Oraz korzystać z google, stack overflow, itd.
Transatlantyk
Użytkownik
Użytkownik
Posty: 52
Rejestracja: 30 cze 2014, o 15:08
Płeć: Kobieta
Lokalizacja: Ziemia

[C++] Wyznaczanie częstotliwości znaków

Post autor: Transatlantyk »

No dpbrze, więc staram się korzystać z inteligencji i możlwosci internetu, poprawiająć kod:

Kod: Zaznacz cały

// ConsoleApplication2.cpp : Defines the entry point for the console application.
//

/*Napisać plik do wyznaczania częstotliwości występowania znaków i dwuznaków w pliku o podanej
nazwie. Plik jest zapisany alfabetem łacińskim (bez znaków diakrytyzowanych). Program wczytuje nazwę
pliku z linii poleceń (po przełączniku -i) i zapisuje wynik do pliku, którego nazwa jest podana po
przełączniku -o. Przykładowe wywołanie programu:
program.exe -o wyjscie -i wejscie
*/

#include "stdafx.h"
#include<iostream>
#include<fstream>
#include<string>

using namespace std;

/*skrót działania:
funkcja odczytująca pliki odczytu i zapisu
funkcja sprawdzająca poprawność wczytanych plików i zwracająca iformację
funkacja licząca dwuznaki w danym pliku
funkcja zapisaująca dane do pliku końcowego*/

char check(char * pliko, char * plikz)
{
	fstream plik;
	void open(const char*plik, ios_base::openmode out);
	plik.open(pliko, ios::out);
	if (plik.good() == true) {plik.close();}
	else{
		do 
			{
			cout << "Plik zapisu nie istnieje, spóbój jeszcze raz" << endl;
			cout << "-o   :: "; cin >> *plikz;
			void open(const char*plik, ios_base::openmode out);
			plik.open(pliko, ios::out);
			} 
		while (plik.good() == true);
	plik.close();

		void open(const char*plik, ios_base::openmode in);
		plik.open(pliko, ios::in);
		if (plik.good() == true) { plik.close(); }
		else {
			do
			{
				cout << "Plik odczytu nie istnieje, spóbój jeszcze raz" << endl;
				cout << "-1   :: "; cin >> *pliko;
				void open(const char*plik, ios_base::openmode in);
				plik.open(pliko, ios::in);
			} while (plik.good() == true);
			plik.close();


			return *plikz, *pliko;
		}

char search(char *pliko, char *plikz)
{
	int dw = 0;
	double result1, result2;
	fstream plik("plikz", std::ios::in);
	string dane;
	getline(plik, dane);
	char y = dane.length();
	y = result1;
	char d = y;
	char ** new char * dane[d];
	int z = 1;
	for (int j = 0; j < d; j++)
	{
		for (int i = 0; i < d; i++)
		{
			if (dane[z - 1] == "c")
			{
				if (dane[z] == "") { dw++; }
				if (dane[z] == "k") { dw++; }
				if (dane[z] == "s") { dw++; }
				if (dane[z] == "z") { dw++; }
				if (dane[z] == "i") { dw++; }
			}
			if (dane[z - 1] == "d")
			{
				if (dane[z] == "z") { dw++; }
				if (dane[z] == "ż") { dw++; }
				if (dane[z] == "ź") { dw++; }
				if (dane[z] == "z") { dw++; }
				if (dane[z] == "z"& dane[z + 1] == "i") { dw++; }
			}
			if (dane[z - 1] == "g")
			{
				if (dane[z] == "l") { dw++; }
				if (dane[z] == "h") { dw++; }
			}
			if (dane[z - 1] == "l") { if (dane[z] == "y") { dw++; } }

			if (dane[z - 1] == "p") { if (dane[z] == "h") { dw++; } }

			if (dane[z - 1] == "q") { if (dane[z] == "u") { dw++; } }

			if (dane[z - 1] == "t") { if (dane[z] == "h") { dw++; } }

			if (dane[z - 1] == "x") { if (dane[z] == "h") { dw++; } }

			if (dane[z - 1] == "c") { if (dane[z] == "i") { dw++; } }

			if (dane[z - 1] == "n")
			{
				if (dane[z] == "g") { dw++; }
				if (dane[z] == "y") { dw++; }
				if (dane[z] == "i") { dw++; }
			}
			if (dane[z - 1] == "n")
			{
				if (dane[z] == "g") { dw++; }
				if (dane[z] == "y") { dw++; }
			}
			if (dane[z - 1] == "s")
			{
				if (dane[z] == "h") { dw++; }
				if (dane[z] == "c") { dw++; }
				if (dane[z] == "z") { dw++; }
				if (dane[z] == "i") { dw++; }
			}
			if (dane[z - 1] == "z")
			{
				if (dane[z] == "h") { dw++; }
				if (dane[z] == "s") { dw++; }
				if (dane[z] == "i") { dw++; }
			}
			if (dane[z - 1] == "r")
			{
				if (dane[z] == "z") { dw++; }
			}
			z++;
		}
	}

	char tab3[1] = { result1, dw };

	return tab3[1];
}



int main(int argc, char *argv[])
{
	argc = 2;
	fstream plik;
	char *plikz, *pliko;
	cout << "-o   :: "; cin >> argv[0];
	cout << "-1   :: "; cin >> argv[1];
	plikz = argv[0];
	pliko = argv[1];
	check(pliko, plikz);
	search(pliko, plikz)
	char data[1] = search(pliko, plikz);
	cout << "Liczba znaków we wczytanym pliku to: " << data[0] << endl 
	<< "Liczba dwuznaków we wczytanym pliku to: " << data[1] << endl;
}




wydaje mi się, że zrobiłam krok na przód. myślę, że mogę osiągnąć dobry poziom w programowaniu a jeśli się mylę, to potrzebuję pofrządnego kopniaka, żebym zaprzestałą prób
kalwi
Użytkownik
Użytkownik
Posty: 1931
Rejestracja: 29 maja 2009, o 11:58
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 145 razy
Pomógł: 320 razy

[C++] Wyznaczanie częstotliwości znaków

Post autor: kalwi »

Kod: Zaznacz cały

int main(int argc, char *argv[])
{
   argc = 2;
To nie tak działa. argc jest już ustalone w momencie uruchomienia programu.

Kod: Zaznacz cały

   cout << "-o   :: "; cin >> argv[0];
Kompletnie źle. Ty ten program masz uruchomić z poziomu konsoli/terminala, i robisz to w ten sposób, że podajesz parametry na start. Takie jak jest w poleceniu.

Kod: Zaznacz cały

program.exe -o wyjscie -i wejscie
Czyli tak:

Chyba, że korzystasz ze środowiska (z tego co widzę, to z Visual Studio). Wtedy podajesz parametry na start dla tego projektu, wtedy szukasz sobie w google hasła
visual studio arguments

Kod: Zaznacz cały

argv[0];
Nie. Pierwszy argument (zerowy) wektora argumentów (argument vector, argv) to jest ścieżka do pliku wykonawczego programu. Czyli jak masz

Kod: Zaznacz cały

program.exe -o wyjscie -i wejscie
to wyjscie jest tożsame z argv[2], bo to -o pomijasz.

Poza tym

Kod: Zaznacz cały

#include<iostream>
#include<fstream>
#include<string>
Po inkludzie się daje spacje.

I tam jeszcze błędy są, ale na razie po kolei.
Transatlantyk
Użytkownik
Użytkownik
Posty: 52
Rejestracja: 30 cze 2014, o 15:08
Płeć: Kobieta
Lokalizacja: Ziemia

[C++] Wyznaczanie częstotliwości znaków

Post autor: Transatlantyk »

Nie rozumidem nic, wybacz ale jestem wkurzona, czyli mam za przeproszeniem "wjeb**" ten
program.exe -o wyjscie -i wejscie zaraz pod bibliotekami?? a gdzie i kiedy użytkownik wprowadza dane? jak to argc ma być ustalone odgórnie, skoro jego wartości mogą być różne? co to w ogóle oznacza "wczytywanie z lini poleceń"?? (((((((((((((((((
kalwi
Użytkownik
Użytkownik
Posty: 1931
Rejestracja: 29 maja 2009, o 11:58
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 145 razy
Pomógł: 320 razy

[C++] Wyznaczanie częstotliwości znaków

Post autor: kalwi »

czyli mam za przeproszeniem "wjeb**" ten
program.exe -o wyjscie -i wejscie zaraz pod bibliotekami
Nie.
Tutaj przykład o co chodzi:

Kod: Zaznacz cały

https://www.youtube.com/watch?v=LU5nQUxaoiU


A potem lektura:


Jak korzystasz z visual studio, a chyba korzystasz: [url]https://www.youtube.com/watch?v=IgbQCRHKV-Y[/url] (tylko wtedy pomijasz ten program.exe)
Transatlantyk
Użytkownik
Użytkownik
Posty: 52
Rejestracja: 30 cze 2014, o 15:08
Płeć: Kobieta
Lokalizacja: Ziemia

[C++] Wyznaczanie częstotliwości znaków

Post autor: Transatlantyk »

coś chyba załapałam, wrzucam część kodu, bo jeszcze siedzę nad jeną funkcją

Kod: Zaznacz cały

// ConsoleApplication2.cpp : Defines the entry point for the console application.
//

/*Napisać plik do wyznaczania częstotliwości występowania znaków i dwuznaków w pliku o podanej
nazwie. Plik jest zapisany alfabetem łacińskim (bez znaków diakrytyzowanych). Program wczytuje nazwę
pliku z linii poleceń (po przełączniku -i) i zapisuje wynik do pliku, którego nazwa jest podana po
przełączniku -o. Przykładowe wywołanie programu:
program.exe -o wyjscie -i wejscie
*/

#include "stdafx.h"
#include<iostream>
#include<fstream>
#include<string>

using namespace std;

/*skrót działania:
funkcja odczytująca pliki odczytu i zapisu
funkcja sprawdzająca poprawność wczytanych plików i zwracająca iformację
funkacja licząca dwuznaki w danym pliku
funkcja zapisaująca dane do pliku końcowego*/

char check(char&wyjscie, char&wejscie)
{
	fstream plik;
	void open(const char*plik, ios_base::openmode out);
	plik.open(&wyjscie, ios::out);
	if (plik.good() == true) { plik.close(); }
	else {
		do
		{
			cout << "Plik zapisu nie istnieje, spóbój jeszcze raz" << endl;
			cin >> wyjscie;
			&wyjscie;
			void open(const char*plik, ios_base::openmode out);
			plik.open(&wyjscie, ios::out);
		} while (plik.good() == true);
		plik.close();

		void open(const char*plik, ios_base::openmode in);
		plik.open(&wejscie, ios::in);
		if (plik.good() == true) { plik.close(); }
		else {
			do
			{
				cout << "Plik odczytu nie istnieje, spóbój jeszcze raz" << endl;
				cin >> wejscie;
				&wejscie;
				void open(const char*plik, ios_base::openmode in);
				plik.open(&wejscie, ios::in);
			} while (plik.good() == true);
			plik.close();
		}
	}
}

char search(char &wyjscie, char &wejscie)
{
	int dw = 0;
	double result1, result2;
	fstream plik;
	plik.open(&wejscie, ios::in);
	string dane;
	getline(plik, dane);
	char y = dane.length();
	y = result1;
	char d = y, z = 0;
	char ** tab = new char*[13]{ "c","g","l","p","q","t","x","d","n","s","z","r" };
	for (int i = 1; i < 2; i++)
	{
		tab[i];
		for (int j = 1; i < 2; j++)
		{
			char tab[]//k,s,z,i
		 //dglpqtxcnszr
		}
}
}

int main(int argc, char *argv[])
{
	
	fstream plik;
	 cin >> argv[0];
	 cin >> argv[1];
	char wyjscie = *argv[0];
	char wejscie = *argv[1];
	check(wejscie, wyjscie);
	search(wejscie, wyjscie);
	//cout << "Liczba znaków we wczytanym pliku to: " << results << endl 
	//<< "Liczba dwuznaków we wczytanym pliku to: " << result2 << endl;
}
kalwi
Użytkownik
Użytkownik
Posty: 1931
Rejestracja: 29 maja 2009, o 11:58
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 145 razy
Pomógł: 320 razy

[C++] Wyznaczanie częstotliwości znaków

Post autor: kalwi »

Kod: Zaznacz cały

int main(int argc, char *argv[])
{
   fstream plik;
    cin >> argv[0];
    cin >> argv[1];
   char wyjscie = *argv[0];
   char wejscie = *argv[1];
Nie, to jest kompletnie źle. Poza tym to nie jest C, tylko C++, więc używaj stringa, a nie chara. argc oraz argv są już z góry ustalone w momencie uruchomienia programu.

I po co ten

Kod: Zaznacz cały

fstream plik;
Przecież to nic nie robi tu.

Tak powinien wyglądać początek:

Kod: Zaznacz cały

int main(int argc, char *argv[])
{
   string wyjscie(argv[2]);
   string wejscie(argv[4]);
Ewentualnie jeszcze wcześniej

Kod: Zaznacz cały

if(argc != ...) // tu kod co się dzieje
-- 17 lis 2016, o 21:31 --

Poza tym..

Kod: Zaznacz cały

   search(wejscie, wyjscie);
w mainie a potem

Kod: Zaznacz cały

char search(char &wyjscie, char &wejscie)
Po raz kolejny - poczytaj o tym czym są tablice i jak to się wiąże ze wskaźnikami.

Kod: Zaznacz cały

   plik.open(&wejscie, ios::in);
analogicznie co wyżej

Kod: Zaznacz cały

   char y = dane.length();
   y = result1;
bez sensu

Kod: Zaznacz cały

 char ** tab = new char*[13]{ "c","g","l","p","q","t","x","d","n","s","z","r" };
Tak się tego nie robi, trzeba jeszcze raz zaalokować pamięć. To jest wskaźnik na wskaźnik i musisz 2 razy tu przeprowadzić alokację. Ale tak czy siak...

Kod: Zaznacz cały

{ "c","g","l","p","q","t","x","d","n","s","z","r" }
Źle, tu powinny być apostrofy, nie cudzysłowia

I co za tym idzie...

Kod: Zaznacz cały

char *tab = new char[12]{ 'c','g'...};

Kod: Zaznacz cały

   for (int i = 1; i < 2; i++)
Świetna pętla, która wykona się cały jeden raz

I kolejne ileś tam błędów. Na logikę aplikacji nawet nie patrzę póki co.
Transatlantyk
Użytkownik
Użytkownik
Posty: 52
Rejestracja: 30 cze 2014, o 15:08
Płeć: Kobieta
Lokalizacja: Ziemia

[C++] Wyznaczanie częstotliwości znaków

Post autor: Transatlantyk »

Kod: Zaznacz cały

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

/*skrót działania:
funkcja odczytująca pliki odczytu i zapisu
funkcja sprawdzająca poprawność wczytanych plików i zwracająca iformację
funkacja licząca dwuznaki w danym pliku
funkcja zapisaująca dane do pliku końcowego*/

string check(string &wyjscie, string &wejscie)
{
	fstream plik;
	void open(const string*plik, ios_base::openmode out);
	plik.open(&wyjscie, ios::out);
	if (plik.good() == true) { plik.close(); }
	else {
		do
		{
			cout << "Plik zapisu nie istnieje, spóbój jeszcze raz" << endl;
			cin >> wyjscie;
			&wyjscie;
			void open(const string*plik, ios_base::openmode out);
			plik.open(&wyjscie, ios::out);
		} while (plik.good() == true);
		plik.close();

		void open(const string*plik, ios_base::openmode in);
		plik.open(&wejscie, ios::in);
		if (plik.good() == true) { plik.close(); }
		else {
			do
			{
				cout << "Plik odczytu nie istnieje, spóbój jeszcze raz" << endl;
				cin >> wejscie;
				&wejscie;
				void open(const string*plik, ios_base::openmode in);
				plik.open(&wejscie, ios::in);
			} while (plik.good() == true);
			plik.close();
		}
	}
}

int search(string &wyjscie, string &wejscie)
{
	int dw, l;
	fstream plik;
	plik.open(&wejscie, ios::in);
	string dane;
	char t=0;
	ofstream plik("C:/Nanoc/data.txt");
	int pozycja = plik.tellp();
	do{
	getline(plik, dane);
	char y = dane.length();
	t=(t = y);
	plik.seekg(y, ios::cur);
	char** textline = new char*[y];
	char tab2[10][4] =
	{
		{ 'h', 'k', 's', 'z' },{ 'z', 'ż', 'ź', },
		{ 'h', 'l', 'n' },{ 'y' },
		{'g', 'y'},{'h'},{'u'},{'z'},
		{'c', 'h', 'z'},{'h', 's'}
	};
	char tab1[12] = { 'c','d','g','l','n','p','q','r','s','t','x','z' };
	for (int n = 0; n < y; n++)
	{
		for (int i = 0; i < 12; i++)
		{
			if (*textline[n] == tab1[i])
			{
				for (int j = 0; j < 4; j++)
				{
					if (*textline[n - 1] == tab2[j][i])
					{
						dw++;
					}
				}
			}

		}
		

	}
	} while
		( pozycja != ios::end);
	return dw, t;
}
	

int main(int argc, char *argv[])
{
	if (argc != 4) {
		cout << "zbyt wiele podanych argumentow"; main(argc, argv);
	}
	string wyjscie=(argv[2]);
	string wejscie=(argv[4]);
	check(wyjscie, wejscie);
	search(wejscie, wyjscie);
	
	//cout << "Liczba znaków we wczytanym pliku to: " << results << endl 
	//<< "Liczba dwuznaków we wczytanym pliku to: " << result2 << endl;
}


błędy, z którymi nie mogę sonie potadzić, to:

Kod: Zaznacz cały


Error (active)		no instance of overloaded function "std::basic_fstream<_Elem, _Traits>::open [with _Elem=char, _Traits=std::char_traits<char>]" matches the argument list	



Error	C2664	'void std::basic_fstream<char,std::char_traits<char>>::open(const char *,std::ios_base::open_mode)': cannot convert argument 1 from 'std::string *' to 'const wchar_t *'		

Błąd ten występuje w każdej funkcji plik.open(), na czerwono podkreślona jest sama kropka i w ogóle występuje problem przy każdym użyciu 'plik.'
kalwi
Użytkownik
Użytkownik
Posty: 1931
Rejestracja: 29 maja 2009, o 11:58
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 145 razy
Pomógł: 320 razy

[C++] Wyznaczanie częstotliwości znaków

Post autor: kalwi »

Kod: Zaznacz cały

 if (argc != 4) 
Jesteś pewna, że 4? Przemyśl to jeszcze raz (wsk.: sprawdź, ile wynosi argc bez podania argumentów)

Kod: Zaznacz cały

   if (argc != 4) {
      cout << "zbyt wiele podanych argumentow"; main(argc, argv);
   }
Po co jest tu

Kod: Zaznacz cały

main(argc, argv);
? Tworzysz nieskończoną pętlę i przepełnienie stosu w ten sposób. No i czemu "zbyt wiele"? Przecież może być podane "za mało" i ten warunek nie będzie spełniony

Kod: Zaznacz cały

string check(string &wyjscie, string &wejscie)
Jeśli przekazujesz przez referencję zmienną (w przypadku stringa raczej lepiej byłoby użyć kopii, ale mniejsza) to dodaj - dla dobrego kodu - const, czyli

Kod: Zaznacz cały

string check(const string &wyjscie, const string &wejscie)
I dalej w tej funkcji

To jest do wywalenia, nie ma żadnego sensu

Kod: Zaznacz cały

   void open(const string*plik, ios_base::openmode out);

Tu

Kod: Zaznacz cały

   plik.open(&wyjscie, ios::out);
nie dajesz & przed wyjscie. Referencja to jest po prostu alias, czyli traktujesz to jako zwykłą zmienną przez całe ciało funkcji, bez żadnego robaka (jak ja nazywam znak ampersanda)

Kod: Zaznacz cały

   plik.open(&wyjscie, ios::out);
zmienia się w

Kod: Zaznacz cały

plik.open(wyjscie, ios::out);
Ewentualnie możesz to uprościć do

Kod: Zaznacz cały

 ifstream plik;
   plik.open(wyjscie);
To jest do wywalenia:

Kod: Zaznacz cały

         &wyjscie;
         void open(const string*plik, ios_base::openmode out);
Linijka 27 do poprawy, wywalić &

Kod: Zaznacz cały

      } while (plik.good() == true);
Raczej

Kod: Zaznacz cały

      } while (plik.good() != true);

Potem - pomyliłaś się z klamerkami. Ten najbardziej zewnętrzny else powinien kończyć się po linijce 29. Dalej błędy się powtarzają, więc już sobie tam poradzisz.

Inna sprawa to fakt, że nie musisz sprawdzać, czy plik wyjściowy istnieje - zostanie on automatycznie utworzony w momencie próby otworzenia go przez strumień ofstream

Na funkcję search póki co nie patrzę.
Transatlantyk
Użytkownik
Użytkownik
Posty: 52
Rejestracja: 30 cze 2014, o 15:08
Płeć: Kobieta
Lokalizacja: Ziemia

[C++] Wyznaczanie częstotliwości znaków

Post autor: Transatlantyk »

Kolejna próba... Jeszcze los rzucił we mnie świnią, bo pisząc, co chwilę zapisuje zmiany. No i akurat jak już miałam wersję kodu, który kompilował się i jedyne uwagi były "possible loss of data", wstawiłam longa bo nie wiedziałam co począć i prawie dotykałam klawiszu f5 visual studio zażądał ode mnie przejścia na wersję płatną(????????????) i nagle straciłam dostęp do kodu......
Wersja którą teraz wklejam to przerobiona wersja poprzednia, tworzona o 2giej w nocy bazując na danych pamięci ram mojego mózgu działającego już 20którąś godzinę....

Nie pamiętam już dokładnie nawet jakie funkcje zawierają się w dodanych bibliotekach. Na szczęście program nie musi być odporny na błędy, ale czy powinnam dopisać kilka linijek które umożliwiłyby użytkownikowi wpisać ponownie nazwę pliku wejściowego jak się pomyli zamiast znów uruchamiać program? No i gdybym wiedziała co znaczy uruchamiać z linii poleceń... Podchodząc to tego programu znałam pojęcie pętli i tablicy... chyba... więc przepraszam że wypisuję często takie bzdury(:


Kod: Zaznacz cały

/*Napisać plik do wyznaczania częstotliwości występowania znaków i dwuznaków w pliku o podanej
nazwie. Plik jest zapisany alfabetem łacińskim (bez znaków diakrytyzowanych). Program wczytuje nazwę
pliku z linii poleceń (po przełączniku -i) i zapisuje wynik do pliku, którego nazwa jest podana po
przełączniku -o. Przykładowe wywołanie programu:
program.exe -o wyjscie -i wejscie
*/

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <windows.h>

using namespace std;

/*skrót działania:
funkcja odczytująca pliki odczytu i zapisu
funkcja sprawdzająca poprawność wczytanych plików i zwracająca iformację
funkacja licząca dwuznaki w danym pliku
funkcja zapisaująca dane do pliku końcowego*/

bool check(const string &wyjscie, string &wejscie)
{
   fstream plik;
   plik.open(wejscie, ios::in);
   if (plik.good() == true) { plik.close(); return 1;}
      else {
            cout << "Plik odczytu nie istnieje" << endl;
            plik.close();
            exit(0);
             }
}

long search(const string &wyjscie, string &wejscie)
{
   long dw=0, t=0, y=0, pozycja=0;
   string dane;
   fstream plik;
   plik.open(wejscie, ios::in);
   pozycja = plik.tellp();
   int z=(y%12);
   int u=(y-z);
                                                            
   char** textline = new char*[y];
   char tab1[12] = { 'c','d','g','l','n','p','q','r','s','t','x','z' };
   char tab2[10][4] =
   {
      { 'h', 'k', 's', 'z' },{ 'z', 'ż', 'ź', },
      { 'h', 'l', 'n' },{ 'y' },
      {'g', 'y'},{'h'},{'u'},{'z'},
      {'c', 'h', 'z'},{'h', 's'}
   };
   char tab1[12] = { 'c','d','g','l','n','p','q','r','s','t','x','z' };

  do{
   plik.seekg(y, ios::cur);
   y=(y+t);
   getline(plik, dane);
   y = dane.length();
   for (int n = 1; n < y; n++)
   {
      for (int j = 0; j < 12; j++)
      {
         if (*textline[n] == tab1[j])
         {
            for (int i = 0; i < 4; i++)
            {
               if (*textline[n - 1] == tab2[j][i])
               {
                  dw++;
               }
            }
         }
      }
    z=z-1;
   }
 }while( z==0 && pozycja != ios::end);
if(u!=)
{
   for (int n = 0; n <u ; n++)
   {
      for (int j = 0; j < 12; j++)
      {
         if (*textline[n] == tab1[j])
         {
            for (int i = 0; i < 4; i++)
            {
               if (*textline[n - 1] == tab2[j][i])
               {
                  dw++;
               }
            }
         }
      }
   }
 }
   return dw, t;
}



int main(int argc, char *argv[])
{
   if (argc != 2) {
      cout << "zla ilosc podanych argumentow";
   }
   string wyjscie=(argv[1]);
   const string wejscie=(argv[2]);
   check(wyjscie, wejscie);
   search(wejscie, wyjscie);
}
kalwi
Użytkownik
Użytkownik
Posty: 1931
Rejestracja: 29 maja 2009, o 11:58
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 145 razy
Pomógł: 320 razy

[C++] Wyznaczanie częstotliwości znaków

Post autor: kalwi »

uno - jako studentka powinnaś mieć dostęp do wersji premium visuala za darmo, popytaj o microsoft dreamspark an uczelni
secundo - Twój kod jest w folderze, gdzie znajdują się pliki projektu (zapewne w moich dokumentach gdzieś)
No i gdybym wiedziała co znaczy uruchamiać z linii poleceń
Przecież masz to pokazane w filmikach, które parę postów wcześniej zalinkowałem.
Znaczy to, że uruchamiasz wiersz poleceń, wpisujesz "nazwa_programu parametry", enter i program się uruchamia
czy powinnam dopisać kilka linijek które umożliwiłyby użytkownikowi wpisać ponownie nazwę pliku wejściowego jak się pomyli zamiast znów uruchamiać program
Nie zaszkodzi.. ale...

Kod: Zaznacz cały

 if (argc != 2) {
      cout << "zla ilosc podanych argumentow";
   }
Źle. Użytkownik podaje 4 parametry, 1 parametr jest zawsze (argv[0], więc w sumie ma być tych parametrów...)

Kod: Zaznacz cały

 string wyjscie=(argv[1]);
   const string wejscie=(argv[2]);
Źle.

Kod: Zaznacz cały

program.exe -o wyjscie -i wejscie

Kod: Zaznacz cały

argv[0] == sciezka do pliku
argv[1] == -o
argv[2] == wyjscie
argv[3] == -i 
argv[4] == wejscie

wtedy
argc = 5
Poza tym:
czy powinnam dopisać kilka linijek które umożliwiłyby użytkownikowi wpisać ponownie nazwę pliku wejściowego jak się pomyli zamiast znów uruchamiać program
Skoro chcesz to zrobić, to po co wejscie jest typu const?

Kod: Zaznacz cały

 string wyjscie=(argv[1]);
Brzydko. Albo

Kod: Zaznacz cały

 string wyjscie = argv[1];

albo

Kod: Zaznacz cały

 string wyjscie (argv[1]);


Tak czy siak się wywoła konstruktor kopiujący.
I w takim razie, skoro już nie sprawdzasz czy plik wyjściowy istnieje (i słusznie), to po co

Kod: Zaznacz cały

bool check(const string &wyjscie, string &wejscie)
ta funkcja przyjmuje parametr wyjscie, skoro i tak nic nie robi?

Kolejna sprawa: funkcja check jest typu bool. Po co? Przecież nawet jeśli coś zwraca (a zwraca), to i tak się nic nie dzieje. Zmień to więc na void.

Kod: Zaznacz cały

void check(string &wejscie)
{
   ifstream plik;
   plik.open(wejscie);
   while(plik.good() != true)
    {
      cout << "Plik odczytu nie istnieje!" << endl;
      cout << "Podaj poprawna nazwe pliku: ";
      cin >> wejscie;
   }
   plik.close();
}
Następnie:
jak piszesz exit(0); to to 0 jest utożsamiane z sukcesem ("pozytywnym" zakończeniem programu) - a u Ciebie to "porażka".

Kod: Zaznacz cały

https://pl.wikibooks.org/wiki/C/exit


Tak samo funkcja search - zwraca typ long i nic z tym dalej nie robi. Poza tym

Kod: Zaznacz cały

   return dw, t;
to jest kompletnie źle
ODPOWIEDZ