Read file, find min and max of numbers in array

dr eu

Grünschnabel
You make suitable functions, that you are using pointers, that you find in handed realistic sequence (float)
largest and smallest element. If functions are successful, return address of largest or smallest element in array,
else return value NULL.
Write and test programm for test of both functions.
Reading of data must be adapted over suitable entry file, readout of results let goes on screen.
Programm must allow calculation of any number of tasks.


Here is my code:


Code:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <iostream>

using namespace std;

#define MAXELEMENTS 100 // MAX numbers of elements 

//function for max element in float array 

float *biggest(float array[],int number) 
{ 
int counter, counter_max; 
float aretheysame=0; 
for(counter=0; counter < number; counter++) 
{ 
if (*(array+counter) > aretheysame) 
{ 
aretheysame = *(array+counter); 
counter_max = counter; 
} 
} 
return(&*(array+counter_max)); 
} 

//function for min element in float array 

float *smallest(float array[],int number) 
{ 
int counter, counter_max=0; 
float aretheysame=array[0]; 
for(counter=0; counter < number; counter++) 
{ 
if (*(array+counter) < aretheysame) 
{ 
aretheysame = *(array+counter); 
counter_max = counter; 
} 
} 
return(&*(array+counter_max)); 
} 


main(void) 
{ 
FILE *in; 
char inter[255]; 
int num_elements=0; 
float element; 
static float array[MAXELEMENTS]; 

float *small,*big; 

printf("Adress and value of max and min element in array\n"); 
printf("Enter file name : "); 
gets(inter); 
in= fopen(inter,"r"); 
if(in == NULL) 
{ 
printf("Error. No file with this name\n"); 
exit(1); 
} 

while (fscanf(in,"%f",&element) != EOF) 
{ 
array[num_elements] = element; 
num_elements++; 
} 
if (num_elements > 1) 
{ 
big=biggest(array,num_elements); 
printf("\nThe adress of max element is %d",&*big); 
printf(", with value %f",*big); 

small=smallest(array,num_elements); 
printf("\nThe adress of min element is %d",&*small); 
printf(", with value %f",*small); 
} 
else 
{ 
; 
} 
fclose (in); 

cin.ignore();
cin.get();
}

And *.txt file:

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


The program find min and max from all numbers in file, not only from numbers in first line, next from second line, and so on... to the EOF.

Where I am doing wrong ? Please, help me ! :confused:
 
Hello dr eu,

in this while-loop is your "mistake":

EOF means "End of file" !
So your while-loop goes through file, until it reachs the end of the file.

Code:
while (fscanf(in,"%f",&element) != EOF)
{
....
}

greetz chris
 
Hey, zur Verschönerung mischst du am Besten nicht C++ (cin) mit C (printf,FILE*,fgets,usw).
Meine Empfehlung wäre daher voll auf C++ umzusteigen.
Dann könntest du auch mit einem dynamischen Array (std::vector<float>) arbeiten, so könnte kein Buffer-Overflow passieren, welcher in deiner Beispieldatei wohl vorkommen wird, da über 100 Werte darin sind.

Außerdem wäre bei der Addresse beim printf wohl ein %p passender gewesen..
Nochwas:
Code:
float* a;
float* b = &*a;
//entspricht:
float* b = a;
Du dereferenzierst nur den Zeiger unnötigerweise um anschließend wieder die Addresse des dereferenzierten Elements zu bekommen...
Das einzige, was das ausmachen kann ist folgendes: falls der Compiler beide Schritte auch tatsächlich ausführt (weil er womöglich nicht erkennt, dass sie sich ausgleichen), kann es zu Fehlern kommen, falls der Zeiger ungütlig ist.

Außerdem dient es der Verständlichkeit, statt *(array+counter); lieber array[counter] zu schreiben.
 
Hello, Beichtpfarrer !

Ich habe dein rat in Rechnung tragen und ins c++ schreiben (nicht ganz, weil mit txt data lesen problemme haben).
Ich habe array raum vergrossern an 1000.

Code:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <iostream>

using namespace std;

#define MAXELEMENTS 1000 // MAX numbers of elements 

//function for max element in float array 
float *biggest(float array[],int number) 
{ 
int counter, counter_max; 
float aretheysame=0; 
for(counter=0; counter < number; counter++) 
{ 
if (array[counter] > aretheysame) 
{ 
aretheysame = array[counter]; 
counter_max = counter; 
} 
} 
return(&array[counter_max]); 
} 

//function for min element in float array 
float *smallest(float array[],int number) 
{ 
int counter, counter_max=0; 
float aretheysame=array[0]; 

for(counter=0; counter < number; counter++) 
{ 
if (array[counter] < aretheysame) 
{ 
aretheysame = array[counter]; 
counter_max = counter; 
} 
} 
return(&array[counter_max]); 
} 


main(void) 
{ 
FILE *in; 
char inter[255]; 
int num_elements=0; 
float element; 
static float array[MAXELEMENTS]; 

float *small, *big; 

cout << "Adress and value of max and min element in array " << endl; 
cout << "Enter file name : "; 
gets(inter); 
in= fopen(inter,"r"); 
if(in == NULL) 
{ 
cout << "Error. No file with this name" << endl; 
exit(1); 
} 


while (fscanf(in,"%f",&element) != EOF) 
{ 
array[num_elements] = element; 
num_elements++; 
} 
if (num_elements > 1) 
{ 

big=biggest(array,num_elements); 
printf("\nThe adress of max element is %d",&*big); 
printf(", with value %f",*big); 

small=smallest(array,num_elements); 
printf("\nThe adress of min element is %d",&*small); 
printf(", with value %f",*small); 

/*
big=biggest(array,num_elements);
cout << endl << "The adress of max element is " << &*big << ", with value " << *big; 

small=smallest(array,num_elements);
cout << endl << "The adress of min element is " << &*small << ", with value " << *small; 
*/
} 

else 
{ 
 cout << endl << endl << "Error in data file ! "; 
} 
fclose (in); 

cin.ignore();
}


Mit printf ins if (num_elements > 1) ist ausgang


Adress and value of max and min element in array
Enter file name : test1.txt

The adress of max element is 4420144, with value 2000.000000
The adress of min element is 4420020, with value -10.000000


mit cout ist:

Adress and value of max and min element in array
Enter file name : test1.txt

The adress of max element is 0x437230, with value 2000
The adress of min element is 0x4371b4, with value -10

Warum ist das so ? :confused:
 
Zuletzt bearbeitet:
Hm, Ich glaube, dass deine for-Schleifen in den Suchfunktionen fehlerhaft sind:
Sie durchlaufen ein Element zu viel, da counter erst nach der Bedingung erhöht wird (das glaube ich jedenfalls, aber ich weiß es nicht sicher, ich habe bis heute keine Ahnung, wie for-Schleifen genau funktionieren...)

Nur, ein anderer Fehler: du wirst cout << flush; ausführen müssen, um die ausgabe anzuzeigen, bevor du mit gets einliest (denke ich). Wenn du mit cin einlesen würdest, wäre das auch kein Problem.

Übrigens ist es in C++ viel einfacher, Text einzulesen, als in C..


Warum ist das so ?
Weil cout eine Reihe von Typen kennt und automatisch erkennt und gewisse Ausgabe-Optionen für sie speichert. Bei den Standart-Einstellungen sieht die Ausgabe eben so aus (für Zeiger einen Hex-Wert, bei floats mit einer kleineren Genauigkeit)
 
Zuletzt bearbeitet:
Die richtige usgang habe ich mit (int) auflosen:

big=biggest(array,num_elements);
cout << endl << "The adress of max element is " << (int)&(*big) << ", with value " << *big;

small=smallest(array,num_elements);
cout << endl << "The adress of min element is " << (int)&(*small) << ", with value " << *small;

aber linie counting losung und da mit calculation of any number of tasks, das kann ich nicht.


Bitte sehr, wenn du kanst, hilfe leisten zu mier, aber nicht theoretisch, sondern mit code !
 
Zuletzt bearbeitet:
Hy!

dr eu hat gesagt.:
big=biggest(array,num_elements);
cout << endl << "The adress of max element is " << (int)&(*big) << ", with value " << *big;

Warum dereferenzierst du den Pointer und wendest dann wieder den Adressoperator an?
big und &(*big) sind doch dasselebe!
Ein guter Compiler sollte das zwar weg-optimieren, aber es macht den Code irgendwie nur unleserlicher

mfg
uhu01
 
Hello !

Ich habe Dev-C++4.9.9.1 Compiler, aber er was ganz zufrieden.
Stimt das, das &(*big) und big ist genauselbe. Ich habe schon das korrigieren. Danke !
Haben du, uhu01 richtige losung fur andere probleme ?
 
Zuletzt bearbeitet:
Hier ist Ubersetzung ins Deutsche (ich hoffe, das ist richtig):


Zusammensetzen zweckentsprechende Funktionen, welche benutzen Zeigefingers, zu finden ins
gegebene reelle Zahlen Zahlenfolge (float) grosster und kleinstes Glied ins feld, sonst
zuruckgeben Eigenwert Null.
Zusammensetzen und ausprobieren programm fur der Test beide Funktionen.
Das Lesen Daten sollen bearbeitet ubergehen dementsprechende Eingangs Datei,
ausschreiben Ergebnis solen gehen auf Bildschirm.
Programm mussen erlauben Kalkulation beliebig Aufgabenzahl.

Die code ins Englisch ist oben.


Bis jetzt habe mich gelungen programm geschreiben,
welche finden grosster und kleinstes Glied ins feld,
aber von alles Zahlen ins Eingangs Datei.
Aber ich wunschen, das programm finden min und max von Zahlen ins eine Reihe,
jedes Reihe wurde eine Kalkulation Aufgabe.
Aber, denn kann ich nicht ! :confused:
 
Zuletzt bearbeitet:
Zurück