C, předání hodnot zpět do funkce main

C++, C#, Visual Basic, Delphi, Perl a ostatní

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod majklb 3. 3. 2011 22:10

Kód: Vybrat vše
void nacteni_souboru(int velikost, int *vstup, int cpocet)
{
  int cti = 0, i;
  const char *VSTUPNISOUBOR = "vstup.txt";
  FILE *cteni;
  cteni = fopen(VSTUPNISOUBOR,"r");
  while(fscanf(cteni, "%d",&cti) != EOF)
    cpocet += 1;
   velikost = cpocet;
  for(i = 0; i < velikost; i++)
    fscanf(cteni, "%d", &vstup[i]);

  fclose(cteni);
  //return (cpocet, velikost, vstup);
}



int main()
{
  //const char *VSTUPNISOUBOR = "vstup.txt";
  const char *SOUCET = "soucet.txt";
  const char *SERAZENI= "MinMax.txt";
  //const char *INTERVALY= "interval od Min.txt";
  int *minMax, *interval, *vstup;
  int i, min, max, velikost = 0, pocet = 0, soucet = 0, cpocet = 0, rozsah_intervalu;
  FILE  *zapis;

  nacteni_souboru(velikost, vstup, cpocet);
  printf("Ve vstupnim souboru je %d cisel, s nimiz bude program pracovat\n", cpocet);
  //velikost = cpocet;
  printf("Zadejte rozsah intervalu do kterych budete chtit vase data tridit: ");
  scanf("%d", &rozsah_intervalu);



Zdravím, potřeboval bych poradit s tím, jak to udělat, aby se mi vracel ukazatel *vstup a cpocet, teď když program spustím, tak se spustí, načte si ty hodnoty a snad je i uloží to pole vstupu, ale jak se přejde do funkce main, tak už jsou všechny hodnoty automaticky vynulované :-( potřebuju nějakou jednoduchou radu, jak to spravit

A ještě mi to hází že je (nebo občas že může být) neinicalizovaná proměnná, tak to řeším tím, že ji při prvním použití přiřadím nulu, je to správné??

Předem díky všem za odpovědi
majklb
Junior

Odeslat příspěvekod pepekpepek 3. 3. 2011 22:23

u toho cpocet nesmis predavat hodnotou ale referenci
pepekpepek
Kolemjdoucí

Odeslat příspěvekod majklb 3. 3. 2011 22:52

a ty načtená čísla mi to bude načítat v pohodě dál? Jsem se na to snažil přijít a udělal jsem z toho místo voidu opět int, jako jsem to už měl(ale četl jsem, že nejde předávat víc hodnot, což já potřebuju), tak to jsem zjistil, že jsem je nikam nepřirazoval, takže proto se mi žádná čísla nepředávala, ale nechápu jakto, že mi to vždy po skončení programu všechny hodnoty vynuluje zase (jestli si to bere z deklarace, kde mám většinu proměnných "inicializovaných" na nulu)
majklb
Junior

Odeslat příspěvekod Bari007 3. 3. 2011 23:13

Asi s Céčkem začínáš, že? Některé části kódu neodpovídají úplně tomu, jak by se to mělo psát... A celkově ten kód je nějaký divný a dost špatně čitelný.

Pokud chceš pracovat jenom s cpocet, tak si dej návratovou hodnotu funkce nacteni_souboru typu integer a vracej si ten cpocet, funkci si volej přímo v printf v mainu, ne tak jak to máš teď. Tvůj zápis mi nedává moc smysl...

Pokud chceš předávat i vstup, alokuj mu paměť pomocí malloc. Ale s tím vstupem už tam pak v mainu nic neděláš, tak nevím...
Bari007
VIP uživatel
Uživatelský avatar

Odeslat příspěvekod majklb 3. 3. 2011 23:26

ahá, díky, ráno vyzkouším, teď to vzdávám. Jinak poznal jsi to dobře, s céčkem začínám (nebo spíš tímhle programem končím :-D díkybohu). A ten program není vůbec celý, jen mi jde o to předání hodnot a zbytek je nepodstatný, ten funguje (dokud jsem se nesnažil i to načítání ze souboru dělat pomocí funkce).-..alokaci tam mám taky, jen až dál v programu (což je asi blbě když o tom tak přemýšlím).
Můj hlavní cíl je ve funkci načíst soubor (do pole), spočítat kolik tam je hodnot a předat do hlavního programu, kde se se vším zase pracuje.
majklb
Junior

Odeslat příspěvekod Bari007 3. 3. 2011 23:42

Tu alokaci paměti bys měl mít ve funkci nacteni_souboru.

Pokud chceš pracovat pouze s hodnotou cpocet, pak ji jednoduše dej do návratové hodnoty té funkce nacteni_souboru. A vypisuj pomocí
Kód: Vybrat vše
printf("Ve vstupnim souboru je %d cisel, s nimiz bude program pracovat\n", nacteni_souboru(velikost, vstup, cpocet));
Bari007
VIP uživatel
Uživatelský avatar

Odeslat příspěvekod majklb 4. 3. 2011 18:37

aháá, díky jdu to vyzkoušet ..a kdybych potřeboval i načíst ty hodnoty z toho souboru ? jde to vyřešit pomocí jedné funkce??

-- 4. 3. 2011 18:09 --

Tak jsem to vyzkoušel a to funguje, ale jde mi ještě o to předání toho celého pole vstup[i], abych i dál v programu mohl pracovat s těmi čísly. Takhle mi to vypíše jen ten počet čísel, ale nic dalšího nefunguje :-(
majklb
Junior

Odeslat příspěvekod Bari007 4. 3. 2011 19:17

O tom poli už jsem psal - alokuj mu paměť ve funkci nacteni_souboru pomocí malloc a pak dereferencí s tím pracuj dál.
Bari007
VIP uživatel
Uživatelský avatar

Odeslat příspěvekod majklb 4. 3. 2011 19:30

ahá, paměť mu už alokuji. a mám s tím dál pracovat jako s int nacteni_souboru teda? jelikož když jsem to zkoušel jako void (někde jsem se dočetl že jedině tak jde načíst více věcí z funkce), tak to nefunguje. Pro jistotu se zeptám, tu derefernci myslíš jak přesně?
Tak ať se snažím jak se snažím, tak to nepředá to pole. vstup má vždycky po přestupu z funkce do mainu adresu 0x0
Naposledy upravil majklb dne 4. 3. 2011 20:08, celkově upraveno 1
majklb
Junior

Odeslat příspěvekod Bari007 4. 3. 2011 20:07

Zde je velice hezky popsané, jak na návrat více hodnot funkce: http://www.jazykc.ic.cz/vyuka/pointery.html
Bari007
VIP uživatel
Uživatelský avatar

Odeslat příspěvekod majklb 4. 3. 2011 20:15

Kód: Vybrat vše
int nacteni_souboru(int velikost, int *vstup, int cpocet)
{
  int cti = 0, i;
  const char *VSTUPNISOUBOR = "vstup.txt";
  FILE *cteni;
  cteni = fopen(VSTUPNISOUBOR,"r");
  while(fscanf(cteni, "%d",&cti) != EOF)
    cpocet += 1;
  velikost = cpocet;
  for(i = 0; i < velikost; i++)
    fscanf(cteni, "%d", &vstup[i]);

  if ((vstup = (int*)malloc(velikost * sizeof(int))) == NULL) {
    printf("Malo pameti!\n");
    exit(1);
  }
  fclose(cteni);
  return cpocet;
}

int main()
{
  //const char *VSTUPNISOUBOR = "vstup.txt";
  const char *SOUCET = "soucet.txt";
  const char *SERAZENI= "MinMax.txt";
  //const char *INTERVALY= "interval od Min.txt";
  int *minMax, *interval, *vstup = 0;
  int i, min, max, velikost = 0, pocet = 0, soucet = 0, cpocet = 0, rozsah_intervalu;
  FILE  *zapis;


  //velikost = nacteni_souboru(velikost, vstup, cpocet);

  //velikost = cpocet;

  printf("Ve vstupnim souboru je %d cisel, s nimiz bude program pracovat\n", cpocet = nacteni_souboru(velikost, vstup, cpocet));
  printf("Zadejte rozsah intervalu do kterych budete chtit vase data tridit: ");
  scanf("%d", &rozsah_intervalu);

  soucet = soucet_cisel(vstup, velikost);



takhle to mám teď. Četl jsem tamto, ale po přečtení nevím zatím moc co se mě týká, tuším, že až to úplně nejvíc dole, ale zase to není úplně můj případ, jelikož já potřebuju předat jak to pole, tak ten cpocet a tam mají jen return a nic zatím (to nevím co znamená, neboli co se předává)
majklb
Junior

Odeslat příspěvekod Nargon 4. 3. 2011 20:23

Mno ukazatele, jsou jedna moznost, ale nejlepsi reseni je pres reference:
staci upravit definici funkce:
int nacteni_souboru(int& velikost, int& *vstup, int& cpocet)

Snad je to dobre (si to moc nepamatuju, c/c++ jsem fakt dlouho nepouzil) ale tahle mala uprava by mela stacit aby veskere hodnoty, ktere do tech promenych nastavis v te funkci, tak aby byly i v tech promenych po tom co ta funkce skonci.
Desktop: Ryzen 7 1800X (3.95GHz, 1.35V), Asus Crosshair VI Hero, 16GB DDR4 Ram (3200MHz), 128GB SSD + 3TB HDD, Nvidia GTX 1080
Notebook: Asus UL50VT 15.6" (SU7300@1.7GHz, 4GB ram, 500GB HDD, Intel GMA 4500MHD + nVidia G210M, dlouha vydrz cca 7+ hod)
Nargon
Moderátor

Odeslat příspěvekod majklb 4. 3. 2011 20:28

zkoušel jsem to a píše mi to že to očekávalo , ; nebo ) ale koukal jsem se na netu a ty reference jsou asi jen pro C++ :'(
majklb
Junior

Odeslat příspěvekod Bari007 4. 3. 2011 21:10

Ano, týká se tě ta část dole, resp. ten poslední příklad. Princip je v tom, že nepracuješ přímo s hodnotou, ale s ukazatelem na tu hodnotu v paměti. A díky tomu s ní pracuješ i v další funkci, protože paměť se uvolňuje po skončení programu nebo pomocí free. V tom posledním příkladu je naprosto jasně vidět, jak se to používá.
Kód: Vybrat vše
int nacteni_souboru(int velikost, int *vstup, int *cpocet)
{
  int cti = 0, i;
  const char *VSTUPNISOUBOR = "vstup.txt";
  FILE *cteni;
  cteni = fopen(VSTUPNISOUBOR,"r");
  while(fscanf(cteni, "%d",&cti) != EOF)
    *cpocet += 1;
  velikost = cpocet;
  for(i = 0; i < velikost; i++)
    fscanf(cteni, "%d", &vstup[i]);

  if ((vstup = (int*)malloc(velikost * sizeof(int))) == NULL) {
    printf("Malo pameti!\n");
    exit(1);
  }
  fclose(cteni);
  return;
}

int main()
{
  //const char *VSTUPNISOUBOR = "vstup.txt";
  const char *SOUCET = "soucet.txt";
  const char *SERAZENI= "MinMax.txt";
  //const char *INTERVALY= "interval od Min.txt";
  int *minMax, *interval, *vstup = 0;
  int i, min, max, velikost = 0, pocet = 0, soucet = 0, *cpocet, rozsah_intervalu;
  FILE  *zapis;


  //velikost = nacteni_souboru(velikost, vstup, cpocet);

  //velikost = cpocet;
nacteni_souboru(velikost, vstup, &cpocet);
  printf("Ve vstupnim souboru je %d cisel, s nimiz bude program pracovat\n", cpocet);
  printf("Zadejte rozsah intervalu do kterych budete chtit vase data tridit: ");
  scanf("%d", &rozsah_intervalu);

  soucet = soucet_cisel(vstup, velikost);

Nedáváš sem ale celý kód, takže nevím, kde a jak se pracuje s tím polem vstup. Nicméně cpocet funguje.

Použil jsem kód z tvého posledního příspěvku (viewtopic.php?p=8077006#p8077006) a upravil jsem jen to nutné, co bylo k tomuto problému potřeba. Na zbytek kódu jsem nesahal a ani nebudu a tím pádem nenesu žádnou zodpovědnost za to, jestli funguje, jak funguje a jakým stylem je psaný.
Bari007
VIP uživatel
Uživatelský avatar

Odeslat příspěvekod majklb 5. 3. 2011 09:45

Kód: Vybrat vše
int nacteni_souboru(int velikost, int *vstup, int *cpocet)
{
  int cti = 0, i;
  const char *VSTUPNISOUBOR = "vstup.txt";
  FILE *cteni;
  cteni = fopen(VSTUPNISOUBOR,"r");
  while(fscanf(cteni, "%d",&cti) != EOF)
    *cpocet += 1;
  velikost = cpocet;
  for(i = 0; i < velikost; i++)
    fscanf(cteni, "%d", &vstup[i]);

  if ((vstup = (int*)malloc(velikost * sizeof(int))) == NULL) {
    printf("Malo pameti!\n");
    exit(1);
  }
  fclose(cteni);
  return;
}


int soucet_cisel(int *vstup, int velikost)
{
  int soucet = 0, i = 0;
  for( i = 0; i < velikost; i++) {
    soucet += vstup[i];
  }
  return soucet;
}



int main()
{
  //const char *VSTUPNISOUBOR = "vstup.txt";
  const char *SOUCET = "soucet.txt";
  const char *SERAZENI= "MinMax.txt";
  //const char *INTERVALY= "interval od Min.txt";
  int *minMax, *interval, *vstup = 0;
  int i, min, max, velikost = 0, pocet = 0, soucet = 0, cpocet = 0, rozsah_intervalu;
  FILE  *zapis;

  nacteni_souboru(velikost, vstup, &cpocet);
  printf("Ve vstupnim souboru je %d cisel, s nimiz bude program pracovat\n", cpocet);
  printf("Zadejte rozsah intervalu do kterych budete chtit vase data tridit: ");
  scanf("%d", &rozsah_intervalu);

  soucet = soucet_cisel(vstup, velikost);
  zapis = fopen(SOUCET,"w+");
  fprintf(zapis,"Celkovy soucet od 1. do %d. císla je %d\n",velikost, soucet);
  fclose(zapis);

  return 0
}

Omlouvám se, chtěl jsem to přidat, aby šlo zkontrolovat jestli už to funguje, ale zapomněl jsem tam dát fci soucet..takže teď by to snad už mělo jít testovat, ale zkoušel jsem to a nefungovalo to :( jelikož cpocet předávám do proměnné velikost (která je int), tak se mi předala nějaká veliká hodnota. Takže tam pravděpodobně neproběhla ani celá fce nacteni_souboru ..a po spuštění programu se mi nezobrazily ani ty hlášky o počtu čísel v souboru a čekání na další tlačítko. Doufám, že po upravení tohoto kódu to bude možné. Stačí mít soubor vstup.txt s pár údaji pod sebou a měl by se pak vytvořit součet čísel v texťáku soucet.txt

majklb
Junior

Další stránka

Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků