Klasa, problem z funkcją

0

Witam.
Stworzyłem klasę words
Która docelowo ma przechowywać wyrazy z pliku.
Chciałbym napisałem która pyta o plik i ładuje wyrazy z pliku do tablicy obiektów klasy words.
Pojawił mi się problem. (Ta tablica obiektów jest jeszcze nie zdefiniowana w funkcji) Jak sobie z tym poradzić?
Mój kod:

 
#include <iostream>
#include <string>
#include <fstream>

using namespace std;
int n_words=0;//number of words
fstream plik;

void ask4file(){
	string file_name;
	do {
		cout<<"Please enter filename\n";
		getline (cin,file_name);
		if(!file_name.size()){//open def file
			plik.open( "code.txt", ios::in | ios::binary );
		}else{
			plik.open( file_name, ios::in | ios::binary );
		}if(plik.good()==0){
			cout << "\nNo such file\n" << std::endl;
		}
	}while (plik.good() == false);
	
	while (plik >> tab[n_words].content){//copy word to array
		n_words++;				
	}
	n_words--;
}

class words{
public:
	int times;
	string content;
};


int main(){
words tab[15];
ask4file();



	plik.close();
	cout<<tab[1].content;
	return 0;
}
0

o_O Stworzyć tablice i przekazać ją do funkcji?

0

Nie rozumiem twojej odpowiedzi. Czy mógłbyś mnie bardziej nakierować?

0

Jeśli nie rozumiesz mojej odpowiedzi to znaczy ze musisz darować sobie klasy na jakiś czas i przeczytac coś na temat podstaw języka. Bo przekazywanie argumentów do funkcji każda książka i kurs omawiają na samym początku.

0

hmm chyba miałem jakieś zaćmienie
oczywiście wystarczyło

 ask4file(tab);

i odpowiednio zmienić funkcje

 void ask4file(words co[]){
	...
	while (plik >> co[n_words].content){
		n_words++;				 
	}
	n_words--;
}

Pojawia się jeszcze jeden problem.
Jak stworzyć tablice składającą się z n_words obiektów? Domyślam się że trzeba użyć wskaźników.

w main
powinno być coś na wzór
words *wskaznik;
wskaznik = new tab[n_words]. I tu jest problem bo n_words jest jeszcze nie znane.
Czy da się to otrzymać za jednym razem?
Czy muszę najpierw otworzyć plik i zliczyć tylko ilość wyrazów, i potem tworzyć tablice obiektów?

0

Możesz. Teraz musisz doczytać na temat wartości zwracanej przez funkcję. Tablicę zaalokujesz sobie wewnątrz funkcji a potem ją zwrócisz (wskaźnik do niej właściwie). Ew możesz wykorzystać <vector> i jako argument funkcji przekazać referencję do wektora zamiast tablice.

0

Napisałem coś takiego lecz stoję w miejscu.

 void ask4file(words co[]){

        string file_name;
        do {
                cout<<"Please enter filename\n";
                getline (cin,file_name);
                if(!file_name.size()){//open def file
                        plik.open( "code.txt", ios::in | ios::binary );
                }else{
                        plik.open( file_name, ios::in | ios::binary );
                }if(plik.good()==0){
                        cout << "\nNo such file\n" << std::endl;
                }
        }while (plik.good() == false);
 
        while (plik >> co[n_words].content){
                n_words++;                                
        }
        n_words--;
}
 

 

int main(){
words *wskaznik;
wskaznik = new words[15]; 
ask4file(wskaznik);
 
 
        plik.close();
        cout<<wskaznik[1].content<<wskaznik[2].content;;
        return 0;
}

Napisz jakąś podpowiedź.
Moja funkcja jest void więc nic nie zwraca
Z tego co mi się wydaje to program musiałby na bieżąco rezerwować pamięć do każdego elementu, ale nie wiem jak z tym sobie poradzić
Nie chcę na razie używać vector.

0

Moja funkcja jest void więc nic nie zwraca

i to właśnie masz zmienić. Niech funkcja zwraca wskaźnik a nie przyjmuje jako argument.

0

Co funkcja ma zwracać?
Napisałem coś takiego lecz nie za bardzo to rozumiem

 words*  ask4file(words co[]){
...
	return co;

}
0

Ech

#include <iostream>
using namespace std;

void funkcjaZwracajacaTabliceIntow(int*& tablica, int& iloscElementow){
  int n = 10; //wczytane z dupy
  iloscElementow = n;
  tablica = new int[n];
  for(int i=0;i<n;i++)
    tablica[i]=i;
}

int main(){
  int* tablica;
  int n;
  funkcjaZwracajacaTabliceIntow(tablica,n);
  for(int i=0;i<n;i++)
    cout<<tablica[i]<< " ";
  return 0;
}
0

Ale ja nie chce tablicy dynamicznej a dynamiczną listę obiektów!
Przekształciłem to na coś takiego ale nie działa. (dalej musi być podana wartość n)

 void funkcjaZwracajacaTabliceIntow(words*& tablica, int& iloscElementow){
	plik.open( "code.txt", ios::in | ios::binary );
	int n = 6; //wczytane z dupy
	iloscElementow = n;
	tablica = new words[n];
	while (plik >> tablica[n_words].content){
		n_words++;                                
	}
}


int main(){
	words *wskaznik;
	int n;
	funkcjaZwracajacaTabliceIntow(wskaznik,n);
		plik.close();
	for(int i=0;i<n;i++)
		cout<<wskaznik[i].content;
	return 0;
}

Wydaje mi się że najłatwiej było by z początku przydzielenie pamięci na jeden obiekt a potem ciągłe go zwiększanie

while (plik >> co[n_words].content){
                n_words++; 
/*zwiększanie pamięci*/                               
        } 

Może dobrym wyborem jest użycie realloc?

0

Dobrym pomysłem jest użycie <vector> albo <list> bo do tego są stworzone.

0

Jeżeli ktoś będzie potrzebował wrzucam gotowy kod

#include <iostream>
#include <string>
#include <fstream>
#include <vector> 
using namespace std;

int n_words=0;//number of words
fstream plik;

class words{
public:
	int times;
	string content;
	words(int a, string b){
		times=a;
		content=b;
	}
};

int main(){

	vector <class words> tab;
	string temp;
	string file_name;
	do {
		cout<<"Please enter filename\n";
		getline (cin,file_name);
		if(!file_name.size()){//open def file
			plik.open( "code.txt", ios::in | ios::binary );
		}else{
			plik.open( file_name, ios::in | ios::binary );
		}if(plik.good()==0){
			cout << "\nNo such file\n" << std::endl;
		}
	}while (plik.good() == false);

	while (plik >> temp){//copy word to array
		tab.push_back(words(n_words,temp));
		n_words++;                                
	}
	n_words--;
	for( int i=0; i<n_words; ++i )
		cout<<tab[i].content;

	return 0;
}

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