Wątek przeniesiony 2014-10-29 13:33 z C/C++ przez ŁF.

Przekazywanie danych tablic miedzy funkcjami

0

Witam serdecznie
jestem totalnym n00bem, dopiero zaczynam swoja przygode z C++ i mam problem zwiazany z przekazywaniem danych.

Podzielilam sobie moj program na 3 pliki. main.. funkcje i messages.
Jako ze program ma byc w domysle 2 jezyczny, chcialam aby w zaleznosci od wybranego przez usera jezyka, wyswietlaly sie odpowiednie komunikaty.

No i tu pojawia sie problem. Na poczatku chcialam to zrobic za pomoca tablic. po wpisaniu tego "na zywca" do pliku messages"

string tablica1 [2][5];
  //PL
tablica1[0][0] = "wybrales polski";
   //FR
tablica1[1][0] = "vous avez choisi la langue francaise";
 

pojawia sie komunikat bledu:
tablica1 does not name a type.

umieszcze to w funkcji komunikaty ();
to z kolei w poliku funkcje, w funkcji wybierz_jezyk() pojawia sie blad ze "tablica1[0][0]" was not declared in this scope.

Probowalam jeszcze wyzucic string tablica1 [2][5]; poza funkcje komunikaty. Wtedy jak najbardziej program sie kompuluje, ale w miejscu gdzie powinien sie pojawic napis wybrales polski, nic sie nie wyswietla.

Identycznie jest gdy probuje rozwiazac problem za pomoca struktur.
prosze o pomoc

1

Pokaż więcej kodu. Zmienne jednej funkcji nie są widoczne w innej, więc pewnie to jest Twoim problemem.

0

super ale nie widzimy kodu, na podstawie errorow moge dac Ci do poczytania

http://stackoverflow.com/questions/2133250/does-not-name-a-type-error-in-c

oraz zebys poczytala o zakresie zmiennych (gdzie sa widoczne a gdzie nie)

0

zawartosc pliku messages :

#ifndef MESSAGES_H_INCLUDED
#define MESSAGES_H_INCLUDED
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;

string tablica1 [2][5];
void komunikaty ()
{
  //PL
tablica1[0][0] = "wybrales polski \n";
   //FR
tablica1[1][0] = "vous avez choisi la langue francaise \n";

}

 

zwartosc pliku funkcje ( tylko funkcja wybierz_jezyk)

 
#ifndef FUNKCJE_H_INCLUDED
#define FUNKCJE_H_INCLUDED
#include <iostream>
#include <cstdlib>
#include <string>
#include "messages.h"
using namespace std;

int kod_j;
//Funkcja Odpowiadajaca za Wybór jezyka Gry
int Wybor_Jezyka()
{

                cout << "Najpierw nalezy wybrac jezyk" << endl;
  WybierzJezyk: cout << "Odpowiednio PL dla POLSKIEGO i FR dla FRANCUSKIEGO" << endl;

                string wybrjezyk;

                getline(cin,wybrjezyk, '\n');
                        if (wybrjezyk == "PL")
                            {
                                kod_j = 1;
                                cout <<  tablica1[0][0] << endl;
                            }
                        else if (wybrjezyk == "FR")
                            {
                                kod_j = 2;
                            }
                        else
                            {
                                cout << "Niewlasciwy wybor" << endl;
                                goto WybierzJezyk;
                            }
                cin.get();
}

generalnie cos tam cyztalam o zasiegu zmiennych, ale mimo to nie moge poradzic sobie z rozwiazaniem tego problemu.

1

ja bym to calkowicie inaczej zrobil.

Po pierwsze, uzylbym mapy dla kilku jezykow
http://www.cplusplus.com/reference/map/map/

po drugie jako value tej mapy dodalbym sciezke do np jsona (albo jsona bym wrzucil do mapy, nie wazne)

po trzecie w jsonie bym napisal do ktorego pola jaka wartosc

Wiec mialbym juz problem z glowy jezeli chodzi o jezyk. Dodanie kolejnego jezyka w jakim kolwiek czasie byloby rzecza prosta. (dodanie nowego pliku)

Mialbym przygotowana strukture danych na ktorej moglbym pracowac.

Zrobilbym klase ktora pozwala zmieniac jezyki i daje dostep do konkretnego rekordu jezeli chodzi o plik z jsona (na tym etapie jezeli nie ma az tak duzo tekstu to bym wczytal to do pamieci [stringa] i po prostu robil finda) oraz wyswietla cala zawartosc jsona.

To by bylo to samo co masz dokladnie teraz :) Ale w bardziej cywylizowany sposob.

Dlaczego warto tak zrobisz? Nauczysz sie znacznie wiecej robiac w ten sposob. Raz ze w bardziej poprawny sposob niz to co teraz masz, a dwa poznasz rzeczy ktorych normalnie bys teraz nie tknela

0

dzieki wielkie :)

a masz moze poradnik do tego wlansie w jakims cywilizowanym jezyku ? francuskim albo polskim ? bo obawiam sie z emoja ksiazka do programowania tego nie zawiera :D

Poszperalam troche po gogle i wiem jendo.. ten sposob - cywilizowany - mnie przerasta.. i jeszcze dlugo bedzie przerastal.... tym bardziej ze ja mimo n-tego przeczyutania dzialu o funkcjach nie bardzo kumam kiedy powinnam stawiac argumenty i jakiego typu dac funkcje...

mozemy wrocic do podstawowej wersji opartej na tablicy lub strukturze ?
Co jest zle w moim kodzie ze nie wyswietla sie prawidlowo ?

1
  1. Gdzie wywołujesz funkcję komunikaty(), która ustawia te teksty?
  2. Jak wybrano francuski to dlaczego już nic nie wyświetlasz?
  3. Nie używaj goto!

Ale zdecydowanie powinnaś próbować rozgryźć wersję, którą @fasadin nakreślił.

0

Rejestracja: 2014-07-08 11:49
Ostatnio: 2 minuty temu
Postów: 241

  1. Gdzie wywołujesz funkcję komunikaty(), która ustawia te teksty?
    no.. na poczatku pliku .. #include <messages.h> .. nie wiedzialam jak ja inaczej wrzucic by byla ona globalna.
  2. Jak wybrano francuski to dlaczego już nic nie wyświetlasz?
    bo kod nie jest skonczony. jesli uda mi sie opanowac to ze zawartosc tej tablicy bedzie sie w ogóle wyswietlac.. bede sie bawic dalej...
  3. Nie używaj goto!
    nie znam innej metody na przechodzenie miedzy blokami.
0

Mylisz definicję funkcji z jej użyciem. Wróć do Twojego kursu, temat funkcje.

0

mam to caly czas przed oczami... inne funkcje dzialaja... stad tez moje pytanie na forum.. gdybym w ksiazce tudzieŻ gdzies indziej w necie ( moze nie wyglada, ale owszem szukalam) znalazla odpowiedz, nie zakladalabym tematu.

1
  1. #include "messages.h" sprawi jedynie, że funkcja komunikaty będzie widoczna, ale to nie znaczy, że ona jest wywołana. Skąd kompilator ma wiedzieć w którym dokładnie miejscu chcesz to wywołać.

  2. Dowolna pętla, w tym przypadku może być while (kod_j != 1 && kod_j != 2)

0

wróć...
dzieki za podpowiedz.. cos udalo sie zrobic.. wewnatrz funkcji wybierz_jezyk

int Wybor_Jezyka()
{
komunikaty();

                cout << "Najpierw nalezy wybrac jezyk" << endl;
  WybierzJezyk: cout << "Odpowiednio PL dla POLSKIEGO i FR dla FRANCUSKIEGO" << endl;

                string wybrjezyk;

                getline(cin,wybrjezyk, '\n');
                        if (wybrjezyk == "PL")
                            {
                                kod_j = 1;
                                cout <<  tablica1[0][0] << endl;
                            }
                        else if (wybrjezyk == "FR")
                            {
                                kod_j = 2;
                            }
                        else
                            {
                                cout << "Niewlasciwy wybor" << endl;
                                goto WybierzJezyk;
                            }
                cin.get();
}
 

i zadzialalo !!

ale da sie to zrobic teraz bardizej globalnie abym nie musiala za kazdym razem tego klepywac ?

0

i kolejne jeszcze pytanie.. obecnie moja funkcja jest typu void.. w jakim przypadku moglaby byc string ?? bo nie kumam ... ( ah ta blond logika ) :)

jejku... ale ja spamuje forum ...

@kq dzieki ci wielkie :) twoj krotki komentarz dal mi na tyle do myslenia.. .ze w koncu wpadlam na to jak to ma byc :) wrzycilam do funkcji main .. i dziala dokladnie tak jak chciałam :)

oczywiscie wszystkim, którzy się udzielali również bardzo dziekuje :)

0

ale da sie to zrobic teraz bardizej globalnie abym nie musiala za kazdym razem tego klepywac ?
Wklepywanie kilku liter komunikaty(); jest takim problemem?

obecnie moja funkcja jest typu void.. w jakim przypadku moglaby byc string ??
Wtedy kiedy będzie zwracać wartość typu string. Swoją drogą WyborJezyka deklaruje, że zwraca int, ale tego nie robi.

0
twonek napisał(a):
  1. #include "messages.h" sprawi jedynie, że funkcja komunikaty będzie widoczna, ale to nie znaczy, że ona jest wywołana. Skąd kompilator ma wiedzieć w którym dokładnie miejscu chcesz to wywołać.

dzieki za rade :) posluchalam i poskutkowalo :)

  1. Dowolna pętla, w tym przypadku może być while (kod_j != 1 && kod_j != 2)

jezeli chodzi o te petle, to ona i tak bedzie zmodyfikowana.. tak aby w zaleznosci od kod_j komunikat, wyswietlal sie od razu we wlasciwym jezyku
tablica[kod_j][0] <--- cos w ten desen chce uzyskac.
A co do go tu.. istotnie, tutaj mozna go ominac.. ale potem pozostaje problem kolejnych przejsc, bo w zasadzie bedzie ich duuuzo wiecej. Tym bardziej ze na koniec programu ( po skonczone rozgrywce gracz bedize mial mozliwosc przejscia do ponownego wybou poziomu... wiec ten goto i tak sie pojawi).

Nie bardzo rozumiem dlaczego tak to jest odradzane. to najprostryz sposob do przechodzenia miedzy blokami.

twonek napisał(a):

ale da sie to zrobic teraz bardizej globalnie abym nie musiala za kazdym razem tego klepywac ?
Wklepywanie kilku liter komunikaty(); jest takim problemem?
niby nie... ale ta funkcja ma sie pojawic we wszystkich mozliwych funckjach.. ale jak juz pisalam.. problem sie rozwiazal :)

obecnie moja funkcja jest typu void.. w jakim przypadku moglaby byc string ??
Wtedy kiedy będzie zwracać wartość typu string. Swoją drogą WyborJezyka deklaruje, że zwraca int, ale tego nie robi.

zwraca kod_j który jest int... w zasadzie po to ta funkcja jest.. aby dac zmienna kod_j tora bedzie dalej uzywana przez caly program

0
int Wybor_Jezyka()
  {
   static const char *Lang[][2]={{"PL","polski"},{"FR","francuzki"}}; // może lepiej strukturę i na zewnątrz
   //komunikaty(); // nie wiem co to i po kiego
   while(true)
     {
      for(unsigned i=0;i<sizeof(Lang)/sizeof(*Lang);++i) cout<<Lang[i][0]<<" - "<<Lang[i][1]<<endl;
      cout<<"Wybierz język: ";
      string lang;
      getline(cin,lang);
      for(unsigned i=0;i<sizeof(Lang)/sizeof(*Lang);++i) if(lang==Lang[i][0]) return i+1;
      cout<<"Niepoprawny wybór"<<endl<<endl;
     }
  }
0

yyy no tak :D tyle ze ja tutaj nie wiem co jak .. po co i dlaczego. A nie chce umieszczac w programie czegos, czego po prostu nie rozumiem.

komunikaty() to funkcja ktora zaiwera cala tablice z komunikatami jakie bedzie zwracal program.

1

zwraca kod_j który jest int... w zasadzie po to ta funkcja jest.. aby dac zmienna kod_j tora bedzie dalej uzywana przez caly program
No to pokaż mi palcem miejsce w kodzie, gdzie jest zwracany kod_j. Bo w tej chwili jedynie modyfikujesz zmienną globalną (kolejna odradzana praktyka), natomiast nic nie zwracasz.

Nie bardzo rozumiem dlaczego tak to jest odradzane. to najprostryz sposob do przechodzenia miedzy blokami.
W pewnych przypadkach rzeczywiście goto jest najprostsze, np. wyjście z kilku zagnieżdżonych pętli. Ale ogólnie nie powinno się tego używać, bo trudno prześledzić przepływ programu i ciężko wyłapać błędy.

0
twonek napisał(a):

zwraca kod_j który jest int... w zasadzie po to ta funkcja jest.. aby dac zmienna kod_j tora bedzie dalej uzywana przez caly program
No to pokaż mi palcem miejsce w kodzie, gdzie jest zwracany kod_j. Bo w tej chwili jedynie modyfikujesz zmienną globalną (kolejna odradzana praktyka), natomiast nic nie zwracasz.

mhm... czyli w sensie dopisanie do funkcji return kod_j; rozwiaze sprawe ? i wtedy jesli umieszcze zmiennna wewnatrz funkcji.. to kod_j bedzie mimo to widoczne w pozostalych funkcjach ?

1

Ale po co sie skupiac na tablicach, stringach i innych malo przyjemnych rzeczach?
Na moje oko to masz jezyk, masz pewna wiadomosc w danym jezyku i masz pewne zrodlo danych, z ktorego ciagniesz te wiadomosci. Nic wiecej.

enum class Language {
  Polish,
  French
};

template <typename Message, typename DataSource>
class Messages {
  typedef function<Message(string)> MsgFactory;
  MsgFactory factory;

  DataSource dataSource;

  unordered_map<Language, Message> data;

  void loadMessage(Language lang) {
    // TODO
  }

public:
  Messages(DataSource ds, MsgFactory factory):
    dataSource(ds), factory(factory) {}

  Message operator[](Language lang) {
    if(!messageExists(lang)) {
      loadMessage(lang);
    }

    return data[lang];
  }

  bool messageExists(Language lang) const {
    return data.count(lang) != 0
  }
};

Na szybko wiec bedzie cos takiego.

0
Pochichrana napisał(a):

mhm... czyli w sensie dopisanie do funkcji return kod_j; rozwiaze sprawe ? i wtedy jesli umieszcze zmiennna wewnatrz funkcji.. to kod_j bedzie mimo to widoczne w pozostalych funkcjach ?
Nie. Nie. Trzeba przeprojektować przepływy inaczej. Wszędzie gdzie chcesz mieć tę wartość musisz ją przekazać. Ale najlepiej tak jak @kq napisał, należy przeczytać porządnie rozdział o funkcjach.

0
twonek napisał(a):
Pochichrana napisał(a):

mhm... czyli w sensie dopisanie do funkcji return kod_j; rozwiaze sprawe ? i wtedy jesli umieszcze zmiennna wewnatrz funkcji.. to kod_j bedzie mimo to widoczne w pozostalych funkcjach ?
Nie. Nie. Trzeba przeprojektować przepływy inaczej. Wszędzie gdzie chcesz mieć tę wartość musisz ją przekazać. Ale najlepiej tak jak @kq napisał, należy przeczytać porządnie rozdział o funkcjach.

no coz.. najwyrazniej jest zbyt gluipia na to :(
bo juz go chyba z 8 razy czytalam... no albo mam jakas wybrakowana ksiazke.. ale raczej to pierwsze...

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