C++ Proč nevidím proměnné ve funkcích které jsou deklarované mimo?

Ahoj, mám takový script, který by měl vypsat jednu položku z pole a počet položek v poli. Fungovalo to, ale problém nastal když jsem to dal do funkcí, jak zpřístupnit proměnnou pole a proměnnou celkem aby se to vypsalo? Děkuji
Kód: [Vybrat]
using namespace std;

string pole [] = {"a", "b", "c"};
int celkem = sizeof(pole) / sizeof(string);

void tiskniPole() {
  printf("%s", pole[4].c_str());
  printf("%s", celkem);
}

void doplnPole() {
  pole[3]="d";
  pole[4]="e";
celkem = sizeof(pole) / sizeof(string);
}

int main() {
  doplnPole();
  tiskniPole();
  return 0 ;
}


Ahoj, mám takový script, který by měl vypsat jednu položku z pole a počet položek v poli. Fungovalo to, ale problém nastal když jsem to dal do funkcí, jak zpřístupnit proměnnou pole a proměnnou celkem aby se to vypsalo? Děkuji
Kód: [Vybrat]
using namespace std;

string pole [] = {"a", "b", "c"};
int celkem = sizeof(pole) / sizeof(string);

void tiskniPole() {
  printf("%s", pole[4].c_str());
  printf("%s", celkem);
}

void doplnPole() {
  pole[3]="d";
  pole[4]="e";
celkem = sizeof(pole) / sizeof(string);
}

int main() {
  doplnPole();
  tiskniPole();
  return 0 ;
}

Tady je tolik věcí špatně, že nevím kde začít. Ten problém je v tom, že přistupuješ mimo paměť (číslujeme od 0).

Ten kód je spíš C, ošklivé C.

  • U stringů stačí std::string pole = "abc".
  • Tím pádem ani nepotřebuješ int celkem, protože stringy (jako jiné kontejnery) typicky mají metodu size, která ti velikost vrátí. Takže to "celkem" by bylo int celkem = pole.size();.
  • Místo céčkového printf používej std::cout << to_co_chci_vypsat;.
Obecněji:
  • Není vhodné používat globální proměnné. Ideálně by funkce doplnPole měla brát referenci na předávané pole/string, který by změnila.
  • Názvy funkcí, proměnných apod. nepiš česky. Ideální je angličtina.

Takže třeba

Kód: [Vybrat]
#include <iostream>
#include <string>

using namespace std;

void printNthChar(const string& s, unsigned n) {
    if ( n < s.size() ) {
        cout << n << ". char is: " << s[n] << "\n" << "size: " << s.size() << endl;
    }
}

void complementString(string& s) {
    s.append("d");
    s.append("e");
}

int main() {
    string str = "abc";
    cout << "str is: " << str << endl;
    complementString(str);
    printNthChar(str, 4);
    cout << "str is: " << str << endl;
    return 0;
}

Ten ampersand (&) značí, že argument je předáván referencí -> bez něj by se vytvořila kopie argumentu, do něj by se přidaly ty prvky/vytisknul by se, ale mimo tu funkci by ten řetězec nebyl modifikován. Zkus si ty ampersandy smazat, program se bude chovat jinak.

Jinak si dávej pozor na přidávání prvků pomocí [] - tento operátor typicky nekontroluje hranice, takže pokud máš pole o délce 5 a zavoláš pole[10], tak se může stát cokoliv.

PS - Příště by to chtělo více popsat, co nefunguje, respektive co to vypisuje. :)
« Poslední změna: 19. 02. 2020, 20:32:26 od Cikáda »

PS - Příště by to chtělo více popsat, co nefunguje, respektive co to vypisuje. :)

Myslím, že jestli mu to kdy vypisovalo něco jiného než segmentation fault, tak to byla jen velká náhoda.

@Cikáda
Díky za poučné slova, ale kde je to pole? Ty jsi vytvořil místo pole pouze řetězec? Děkuji

PS: ten kod byl jen pro ukázku - byl hodně zkrácený.
« Poslední změna: 19. 02. 2020, 20:57:08 od petr_bures »

Díky za poučné slova, ale kde je to pole? Ty jsi vytvořil místo pole pouze řetězec? Děkuji

To pole je ten řetězec. Jestli jsi chtěl mít pole řetězců, tak to není problém napsat.

Mimochodem doporučuji místo pole používat vector, když už jsme v C++. Víc najdeš na https://en.cppreference.com/w/.


Mimochodem doporučuji místo pole používat vector, když už jsme v C++.
Vector funguje parádně - díky za tip.

Ten printf () jsem používal z důvodu toho, že umí různé fičury jako obarvit texty a hlavně umí pracovat z kurzorem.

Pokud se budu držet tvých rad, můžeš mi prosím ještě poradit jak skrýt v console Windows cursor a jak tisknou text vždy od začátku řádku, při použití
cout << "Nějaký text" endl;

Díky moc.

Mimochodem doporučuji místo pole používat vector, když už jsme v C++.
Vector funguje parádně - díky za tip.

Ten printf () jsem používal z důvodu toho, že umí různé fičury jako obarvit texty a hlavně umí pracovat z kurzorem.

Pokud se budu držet tvých rad, můžeš mi prosím ještě poradit jak skrýt v console Windows cursor a jak tisknou text vždy od začátku řádku, při použití
cout << "Nějaký text" endl;

Díky moc.

To určitě půjde i bez printf, ale určitě není problém jej používat. Windows už naštěstí nevedu, takže neumím poradit. Google ale určitě něco najde.