» »

[C++][Naloga_polja]MIN in MAX polja, izpis za x.100 stevil

[C++][Naloga_polja]MIN in MAX polja, izpis za x.100 stevil

dr.eu ::

PROSIM, če mi kdo lahko pomaga pri naslednji nalogi:

Sestavi ustrezni funkciji, ki uporabljata kazalce, da poiščeta v podanem realnem zaporedju (float) največji
in najmanjši element. Če sta funkciji uspešni, vrneta naslov največjega oz. najmanjšega elementa v polju,
sicer pa vrneta vrednost NULL.
Sestavi in preizkusi program za test obeh funkcij.
Branje podatkov naj bo prirejeno preko ustrezne vhodne datoteke, izpis rezultatov pa naj gre na zaslon.
Program mora omogočati izračun poljubnega števila nalog.

Napisal sem spodnjo kodo v C++:


#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <stdio.h>

#define MAXELEMENTOV 100    // maksimalno število elementov v nalogi

/* Funkcija za določitev največjega elementa v realnem zaporedju */
float *najvecji(float tabela[100],int stevilo)
{
int stevec,stevec_max;
float primerjaj=0;
for(stevec=0;stevec < stevilo;stevec++)
   {
    if (*(tabela+stevec) > primerjaj)
     {
      primerjaj = *(tabela+stevec);
      stevec_max = stevec;
     }
   }
return(&*(tabela+stevec_max));
}

/* Funkcija za določitev najmanjšega elementa v realnem zaporedju */

float *najmanjsi(float tabela[100],int stevilo)
{
int stevec,stevec_max=0;
float primerjaj=tabela[0];
for(stevec=0;stevec < stevilo;stevec++)
{
   if (*(tabela+stevec) < primerjaj)
   {
    primerjaj = *(tabela+stevec);
    stevec_max = stevec;
   }
}
return(&*(tabela+stevec_max));
}

/* Glavna funkcija */
main(void)
{
FILE *vhod;
char vhodna[255];

float element;
static float tabela[MAXELEMENTOV];
int st_elementov=0;

float *najmanj,*najvec;

printf("Naslov na najvecji in najmanjsi element v polju \n");
printf("\n\n\nIme vhodne datoteke : ");
gets(vhodna);
vhod= fopen(vhodna,"r");
if(vhod == NULL)
{
   printf("Ne morem odpreti datoteke za branje podatkov\n");
   exit(1);
}

while (fscanf(vhod,"%f",&element) != EOF)
{

for(st_elementov=0; st_elementov<100; st_elementov++)
   {
st_elementov;

   tabela[st_elementov] = element;
   element++;
   st_elementov++;

   }



if (st_elementov > 1)
{
   najvec=najvecji(tabela,st_elementov);
   printf("\nNaslov najvecjega elementa je %d",&*najvec);
   printf(", ki ima vrednost %f",*najvec);
   najmanj=najmanjsi(tabela,st_elementov);
   printf("\nNaslov najmanjsega elementa je %d",&*najmanj);
   printf(",ki ima vrednost %f",*najmanj);
}

   else
   {
    ;
   }

    }

fclose (vhod);

getchar();
}



Še vhodna datoteka .txt (vpisal sem samo int, morajo pa biti upoštevani float):

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2000 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
15 14 13 22 55 2 5


Izpiše mi sicer MIN in MAX element v polju, vendar od vseh cca 300 realnih števil,
ne pa od prvih 100, nato od naslednjih 100, itd., ker naloga zahteva namreč izračun poljubnega števila nalog.

Kje delam narobe ? :O
Lp, dr.eu

Gundolf ::

Nikjer ti ne piše, da morajo naloge vsebovati 100 števil. Poskusi narediti brez take zelo umetne meje. Predlagam da posamezno 'nalogo' zaključiš s posebnim znakom, recimo z X. Ko se bo fscanf pritožil boš vedel, da je prebral znak, ko je pričakoval številko in boš lahko zaključil z nalogo ter začel novo.

dr.eu ::

Nikjer ti ne piše, da morajo naloge vsebovati 100 števil. Poskusi narediti brez take zelo umetne meje. Predlagam da posamezno 'nalogo' zaključiš s posebnim znakom, recimo z X. Ko se bo fscanf pritožil boš vedel, da je prebral znak, ko je pričakoval številko in boš lahko zaključil z nalogo ter začel novo.

Vsaka naloga bi naj bila v .txt datoteki v svoji vrstici in ko bere naslednjo vrstico, je to tudi naslednja naloga (zato sem si zadal to mejo 100 števil v zaporedju -NI PA NUJNO, kot praviš)

Na primer, ko sem naredil program za izračun trikotnika s vhodnimi podatki za en trikotnik, je bila txt datoteka takšna:
3.0 4.0 90 00 00

za več trikotnikov pa:

20.5 20.5 102 47 36
198.624 257.835 88 00 09
78.294 78.294 57 29 48
16.197 49.008 99 58 17

Mi lahko konkretno pomagaš ?
Lp, dr.eu

OwcA ::

Pred
for(st_elementov=0; st_elementov<100; st_elementov++)
postavi vse relevantne spremenljivke na 0 oziroma jih sprazni.

Program ti bo čudno delal, če bo manj kot 100 podatkov v vrstici.

Rešitev je zelo grda.

Kaj dela "osamelec" st_elementov; za for?

Inicializiraj vse spremenjlivke, ko jih deklariraš.

Kar ti pišeš NI C++, ampak neko skrupucalo, oziroma skorajda čisti C.

Kaj čaraš s static?
Otroška radovednost - gonilo napredka.

dr.eu ::

while (fscanf(vhod,"%f",&element) != EOF)
{

for(st_elementov=0; st_elementov<100; st_elementov++)
   {
st_elementov;

   tabela[st_elementov] = element;
   element++;
   st_elementov++;

   }

Števec st_elementov sem hotel imeti za štetje števil do 100, zato da bi za vsaki 100 imel nato 1., 2., itd. naloga. Prvotno sem imel:

  
while (fscanf(vhod,"%f",&element) != EOF)
  {
   tabela[st_elementov] = element;
   st_elementov++;
  }
  if (st_elementov > 1)
  {

Napisal sem res bolj v C, ker mi odpiranje, branje in zapisovanje datoteke nekako ni delalo.
Mi lahko prosim konkretno pomagaš, ker naloga mora biti v C++ ?
Lp, dr.eu

OwcA ::

Ugh? Kaj si hotel povedati/pokazati?

O C++ imaš pa zelo dober članek prav tu.
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenilo: OwcA ()

dr.eu ::

S konkretno pomočjo nisem mislil na teorijo ... :|
Lp, dr.eu

OwcA ::

Jst pa ne programiranja namesto tebe.

Lahko ti pomagam, povem kaj ni vredu, ampak to je kar se mene tiče to, za več me lahko najameš kot svetovalca ali programerja, ako se ti zdi potrebno.
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenilo: OwcA ()

dr.eu ::

O.K., fer si res. Vendar kot študent nimam toliko denarja, da bi plačeval drage programerje.
Vem, izpit iz prog bom pa vseeno moral narediti...
Lp, dr.eu

OwcA ::

Ker sem dober kot kruh, če si naklikaš stare teme na tem forumu, kjer je govora o C++, boš nedovmno našel kar nekaj primerov uporabe tokov in ostale navlake.
Otroška radovednost - gonilo napredka.

mISOk ::

while ((fscanf(vhod,"%f",&element) != EOF)&&(st_elementov < 100))
{ tabela[st_elementov] = element;
element++;
st_elementov++;

}

To sem ti pogledal to while zanko. zdaj dela dokler je nekaj v datoteki ali dokler ne prebere 100 elemetov. Potem se zaključi.

float *najvecji(float tabela[100],int stevilo)
{
int stevec,stevec_max;
float primerjaj=0;
for(stevec=0;stevec < stevilo;stevec++)
{
if (*(tabela+stevec) > primerjaj) //tole mi je mal čudno a ni tabela[stevec]

{
primerjaj = *(tabela+stevec);
stevec_max = stevec;
}
}
return(&*(tabela+stevec_max));

Čeprav tvoje naloge najbolj ne razumem. Funkcija naj bi bila kazalec na število v tabeli ali datoteki. Sicer nisem kaj preveč programiral v C++ (bolj delphi), ampak kje imaš deklariran kazalec, ali tega ne potrebuješ v C++! Malo bolj opiši!

LP
mISOk
=]

dr.eu ::

Ja, pa si res dober. Hvala. 8-)
Lp, dr.eu

dr.eu ::

Zahvala gre mlSOk-u.
Lp, dr.eu

OwcA ::

@mISOk: nisem prepričan, da je tvoja rešitev vredu, če prav razumem, on hoče prebrati poljubno mnogo vrstic z do 100 vrednostmi.
Otroška radovednost - gonilo napredka.

dr.eu ::

V začetku sem si zamislil shranjevanje podatkov v tabelo, zato tabela.

Vsaka vrstica v datoteki (ni nujno, da vsebuje 100 realnih števil, lahko jih več ali pa manj) je oštevilčena naloga, saj naloga zahteva rešitev poljubnega števila nalog.
Lp, dr.eu

Gundolf ::

Spremeni zanko tako, da bo brala le do konca vrstice nato pa dodaj zunaj še eno zanko, ki se bo sprehajala čez posamezne naloge. Kar se pa streamov tiče so pa simpl kot pasulj.

std::ifstream input;
input.open("blabla.txt");
if  (input.eof()) return;
double cifra;
input >> cifra;
std::cout << "tole je pa izpis " << cifra << std::endl;

Takole približno izgleda uporaba c++ funkcij - vključuje vso funkcijonalnost, ki jo ti uporabljaš. Za rešitev problema z vrsticami bi pa jaz naredil tako, da bi iz inputa prebral eno vrstico v string, iz tega stringa tvoril stringstream in nato v notranji zanki (ki predela eno celo nalogo) bral iz tega streama.

Uporabiš torej headerje iostream (za izpis na zaslon), fstream (delo s faji), sstream (stringstream clas) in string (string class), poglej pa si še globalno funkcijo getline(istream, string)).

[edit - popravil tt v txt in zbrisal en !]

Zgodovina sprememb…

  • spremenil: Gundolf ()

dr.eu ::

std::ifstream input;
input.open("blabla.tt");
if (!input.eof()) return;
.
.
V tem primeru je ime vhodne datoteke že določeno blabla.txt, ije tako ?
Jaz bi pa želel, da uporabnik vnese poljubno ime svoje vhodne datoteke.

Verjetno si spregledal, da moram podatke iz datoteke zapisati v polje,
ne pa v string (verjetno bi tudi string z atoi spremenil in nato zapisal v polje ?)
Lp, dr.eu

Gundolf ::

Močno dvomim da sem to spregledal, prej bi rekel da sem ti le naštel vse ukaze, ki bi jih ti lahko uporabil pri tem, ko bi pisal program.

Morda bi ti moral napisati takole.
double cifre[100];
for (int i = 0; (i < 100) && (!input.eof()); ++i) {
   input >> cifre[i];
}


Upam da je zdaj bolj jasno.

dr.eu ::

Ja, Gundolf, mislim da je, ja sigurno je, ja veš da je, ... No resno, bom upošteval tvoje nasvete in poskusil znova napisati to nalogo. Seveda pa še prej pogledati malo literature, priročnike online, pa bom verjetno čez kakega pol leta le napisal to nalogo ( in se bom lahko hvalil, da sem napisal ta program čisto sam, brez kakršne koli pomoči programerjev !)
Lp, dr.eu

Gundolf ::

Zaznavam kanček sarkazma v tvojem postu dr.eu :D Tako da nadaljujva v istem stilu.

Moja napaka, ker sem mislil, da znaš vsaj toliko programirati, da bos znal sestaviti kodo, ki sem jo podal, in tvoj program. To napako bom zdaj popravil in napisal tole s tvojo terminologijo, hkrati pa bom gratis dodal še kodo, ki ti bo znala rešiti več nalog v istem fajlu8-O :

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

std::ifstream vhod;
input.open(vhod);
if (!input.is_open()) return;

while (!vhod.eof()) {
   std::string naloga;
   std::getline(vhod, naloga);

   std::stringstream nalogaStream(naloga);
   float tabela[100];
   int st_stevil;

   for (st_stevil = 0; (st_stevil < 100) && (!nalogaStream.eof()); ++st_stevil) {
      nalogaStream >> tabela[st_stevil];
   }
}

Ampak ker sem zloben >:D in sem tu pravzaprav le zato, da se v glavo smejim tistim, ki ne znate programirat bom tebi prepustil zafrkavanje z debugiranjem kode (navsezadnje sem le tak maher v programiranju, da si dovolim pisati kar na pamet) in njenim prenašanjem v tvoj program.

Zgodovina sprememb…

  • spremenil: Gundolf ()

dr.eu ::

Gundolf, pa si verjetno res malo zloben ... Kakor koli. Malo sem popravil in preuredil kodo,
dodal nekaj tvoje, toda žal ne morem uporabiti #include sstream ali pa sstream.h,
ker mi javlja sporočilo, da ni takšne datoteke ali direktorija.
Delam z Dev-C++ 4.



#include <iostream.h>
//#include <sstream.h>
#include <fstream.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

using namespace std;

/* Funkcija za določitev največjega elementa v realnem zaporedju */
float *najvecji(float polje[], int stevilo)
{
  int stevec, stevec_max;
  float primerjaj = 0;
  for(stevec = 0; stevec < stevilo; stevec++)
   {
    if (*(polje) > primerjaj)
     {
      primerjaj = *(polje);
      stevec_max = stevec;
     }
   }
  return(&*(polje + stevec_max));
}

/* Funkcija za določitev najmanjšega elementa v realnem zaporedju */
float *najmanjsi(float polje[],int stevilo)
{
  int stevec, stevec_max = 0;
  float primerjaj = polje[0];
  for(stevec = 0; stevec < stevilo; stevec++)
  {
   if (*(polje) < primerjaj)
   {
    primerjaj = *(polje);
    stevec_max = stevec;
   }
  }
  return(&*(polje + stevec_max));
}


main()
{
 char vhod[80];
 int naloga = 1;
 int i, stevilo;
 int st_elementov;
 float najmanj, najvec;
 float polje[0];

 std:: ifstream (vhodna);
 vhodna.open(vhod);

 if (!vhodna.is_open())
 {
  cout << "\a\n\n\n\n\n\n\n\n\n\n\t NAPAKA !!!  Datoteka z imenom " << vhod << " NE OBSTOJA ! " << endl << endl << endl;
  cout << "Pritisni tipko [ENTER] za izhod ... ";
  cin.ignore(); //ignore() poskrbi, da se trenutni vhodni tok počisti (ignorira)
  cin.get(); //get() čaka uporabnikov vnos znaka
  return (0); //EXIT_FAILURE);
 }

 cout << "NASLOV IN VREDNOST NAJMANJSEGA IN NAJVECJEGA ELEMENTA V POLJU" << endl << endl << endl;
 cout << "Vtipkaj ime in tip datoteke ter pot >>>  ";
 cin >> vhod;
 //cin.ignore(); //ignore() poskrbi, da se trenutni vhodni tok počisti (ignorira)


 while (!vhodna.eof())
 {
  std:: string naloga;
  std:: getline(vhodna, naloga);

  std:: stringstream nalogaStream(naloga);
  float polje[100];
  int st_stevil;


  for (st_stevil = 0; (st_stevil < 100) && (!nalogaStream.eof()); ++st_stevil)
  {
   nalogaStream >> polje[i];
  }
 }

 if (st_elementov > 1)
 {
  najvec = najvecji(polje, st_elementov);
  cout << endl << "Naslov navečjega elementa je " << &*najvec << ", ki ima vrednost " << *najvec << endl<< endl;
  najmanj = najmanjsi(polje, st_elementov);
  cout << "Naslov najmanjšega elementa je " << &*najmanj) << ", ki ima vrednost " << *najmanj << endl << endl;
 }

 else
 {
  cout << "\a\n\n\n\n\n\n\n\n\n\n\t NAPAKA !!!  Premalo elementov ! " << endl << endl << endl;
  cout << "Pritisni tipko [ENTER] za izhod ... " ;
  cin.ignore(); //ignore() poskrbi, da se trenutni vhodni tok počisti (ignorira)
  cin.get(); //get() čaka uporabnikov vnos znaka
  return (0); //(EXIT_FAILURE);
 }

 vhodna.close();

 cout << "Pritisnite ENTER za izhod... " ;
 cin.ignore(); //ignore() poskrbi, da se trenutni vhodni tok počisti (ignorira)
 cin.get(); //get() čaka uporabnikov vnos znaka

 return (0); // vrnemo nič //(EXIT_FAILURE);
}




Javljene imam te napake :

`::string' undeclared (first use here)
parse error before `;'
`::getline' undeclared (first use here)
`::stringstream' undeclared (first use here)
parse error before `('
`nalogaStream' undeclared (first use this function)
(Each undeclared identifier is reported only once
for each function it appears in.)
assignment to `float' from `float *'
invalid type argument of `unary *'
invalid type argument of `unary *'
assignment to `float' from `float *'
invalid type argument of `unary *'
parse error before `)'

Vidiš, da sem se potrudil popraviti kodo, vendar ne dela. Daj no, pomagaj mi ! :\
Lp, dr.eu

Gundolf ::

Hm, imaš pa staro STL knjižnjico (take ponavadi pridejo skupaj s starimi prevajalniki), da nima sstream-a. Morda bi ti tu znal pomagati kdo, ki tudi uporablja Dev C++ oz. Mingw prevajalnik. Poskusi za začetek poiskati datoteko "sstream" v tvojem direktoriju od prevajalnika.

Morda bi se dalo namesto branja ene vrstice naenkrat le preverjati, če se v vhodnem streamu na koncu vrstice. S tem bi se izognil uporabi stringstream-ov, a pustimo zaenkrat tole, najprej popravi naslednje.

Napaka (vsaj prva) je pa zato ker si includal string.h in ne string (ti dve stvari sta popolnoma različni - drug header je namreč C-jevska knjižnica). V principu se includa vse headerje, ki nimajo končnice .h (to je C++ standard). Vse kar te headerji vsebujejo je v namespace std. Vidim da uporabljaš using namespace std; tako da ti potem ni treba pisati std::ifstream in podobno ampak le ifstream.

Ostalih nekaj napak je zato ker nimaš vključenih string in sstream. Tiste ki omenjajo floate pa ne vem od kod so (verjetno ti za vsako napako piše, v kateri vrstici je, tako da poskusi to izkoristiti)

Na hitro me je zmotil še tvoj komentar na cin.ignore(); ki pravzaprav naredi to, da prebere iz streama en znak a ga ignorira (ne shrani nikamor).

Še eno napakico sem našel v moji kodi. Sem uporabljal en i, ki ga nebi smel. Tiste float* tabela in ostalo kar že imaš definirano pusti definirano tam kot je bilo. Jaz sem dodal samo za to, da se vidi katerega tipa posamezna stvar sploh je.

snow ::

Daj si zadnji dev-c++ dol. 5.9.9.neki se mi zdi.

Tam laufa sstream.
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

(težava) long long v C

Oddelek: Programiranje
5932 (688) technolog
»

Združevanje polj [C]

Oddelek: Programiranje
7980 (844) ragezor
»

Spreminjanje vrednosti v polju [C]

Oddelek: Programiranje
102167 (1966) specing
»

[C] Vsota števil v polju

Oddelek: Programiranje
51269 (1207) Cvenemir
»

[C] Narascajoce sortiranje linearnega seznama

Oddelek: Programiranje
71856 (1745) Jebiveter

Več podobnih tem