C - reading-mehrere Integer und Fließkommazahlen mit sscanf
Ich mache ein Praxis-problem für meine C-Programmierung Klasse, das sagt mir ein Programm zu schreiben, das liest Variablen aus einer Datei. In der ersten Zeile, es soll gelesen, in einen ganzzahligen N.
Von dort aus, sollte es Lesen eine ganze Zahl, und dann fünf schwimmende Punkte vor jeder Zeile für N Zeilen. Es soll zum berechnen einer Summe von all dem schwebt in der Datei und schreiben in eine andere Datei.
Ich habe ein Programm geschrieben, dass, sollte dies tun, mit fgets zum kopieren einer Zeile in einen string, und sscanf sind, es zu zergliedern und ordnen Sie die Segmente auf unterschiedlichen array-Standorten. Allerdings bin ich auf einige Problem mit der Beschaffung von externen Informationen durch sscanf (vielleicht ein null-Wert oder der Zeilenumbruch). Es ist nicht die Speicherung der integer-N richtig (es ist die Herstellung von großen zufälligen Werten und erstellen eines runtime Fehler durch unendliche Schleife), und es ist wohl nicht arbeiten im inneren der Schleife entweder.
Wie kann ich perfekt an, so dass es liest die Integer-und float-richtig?
#include <stdio.h>
#include <stdlib.h>
#define MAX_STRING 30
#define MAX_LINE_SIZE 200
int main(void)
{
FILE *f1, *f2;
char filename[MAX_STRING];
char fileline[MAX_LINE_SIZE];
int N, eN;
float totalwage = 0;
int* ssn;
float** wage;
printf ("Enter a file name for data analysis: ");
scanf ("%s", &filename); //get file name from user input for reading
f1 = fopen (filename, "r");
fgets (fileline, MAX_LINE_SIZE, f1); //read first line
sscanf (fileline, "%d", &N); //pull integer from first line to determine how many lines follow
for (eN = 0; eN < N; eN ++) //read N lines following the first
{
//VVV read single line from file
fgets (fileline, MAX_LINE_SIZE, f1);
//VVV record data from line
sscanf (fileline, "%d, %f, %f, %f, %f, %f", &ssn[eN], &wage[eN][0], &wage[eN][1], &wage[eN][2], &wage[eN][3], &wage[eN][4]);
//VVV add the 5 wages on each line to a total
totalwage += wage[eN][0] + wage[eN][1] + wage[eN][2] + wage[eN][3] + wage[eN][4];
}
fclose (f1);
printf ("Enter a file name for the result: ");
scanf ("%s", &filename); //get file name from user input for writing
f2 = fopen (filename, "w");
fprintf (f2, "%f", totalwage); //store total of wages in file specified by user
printf ("\nThe information has been stored. Press any key to exit.\n");
getchar();
}
Die Datei gelesen wird 'wages.txt' und seine Inhalte sind wie folgt:
10
1, 10, 20, 30, 40, 50
2, 11, 12, 13, 14, 15
3, 21, 23, 25, 27, 29
4, 1, 2, 3, 4, 5
5, 30, 60, 90, 120, 150
6, 37, 38, 39, 40, 41
7, 40, 50, 60, 70, 80
8, 5, 10, 15, 20, 25
9, 80, 90, 100, 110, 120
10, 1000, 2000, 3000, 4000, 2000
Als eine Zusammenfassung, das Problem ist, dass es ist ein Laufzeit-Fehler, bei dem das Programm abstürzt wegen zu einer Art von Endlosschleife. Durch einige debugging-ich sah, dass es nicht das Lesen in der ersten Zeile als integer richtig. Anstatt den Wert ten, es war die Speicherung von großen Werten, als wenn Sie es Lesen ein null-Zeichen.
Ich habe code versucht, Speicher für ssn und Löhne. Allerdings bin ich mir nicht sicher, ob es richtig gemacht wurde, und das Programm hat noch einen Absturz runtime error.
ssn = malloc (N*MAX_STRING);
wage = malloc (N*MAX_STRING);
for (eN = 0; eN < N; eN ++)
{
wage[eN] = malloc (N*MAX_STRING);
}
- "C - reading-mehrere Integer und Fließkommazahlen mit sscanf" - Nein, mit
fgets()
undstrtol()
undstrtod()
. Darüber hinausscanf ("%s", &filename);
wird ein type mismatch-basierte UB. Die langesscanf()
Linie mit derwage
Zeiger ist auch die UB, da, dass der Zeiger nicht überall, es ist nicht initialisiert. - Nicht einen return-Wert überprüfen von jedem dieser Bibliothek ruft. Und Sie Fragen sich, was kann schief gehen?
- Ich habe erfolgreich zugewiesenen Speicher für ssn und Lohn. Ich bin noch immer unvorhersehbare Werte von sscanf.
- Wenn Sie nicht etwas zu tun, außer die Summe der Löhne, dann brauchen Sie nicht ein array groß genug, um alle halten die Löhne. Möglicherweise müssen Sie ein array groß genug, um eine Zeile Wert der Löhne (also einem einzigen Aufruf
sscanf()
liest die Daten in das array, und dann Sie Summe der array in der Summe. Man könnte sogar den code so schreiben Sie nur ein einzigesfloat
variable zu Lesen, Werte in, plus der man die Summe der Löhne, aber das ist ein bisschen schwieriger und wahrscheinlich nicht der Mühe Wert.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als von anderen darauf hingewiesen
werden sollte:
Beachten Sie, dass
sscanf
ist ein großes problem, wenn die Anzahl der Spalten ändernÜberarbeitet für die Verwendung mit
strtod
:Beachten Sie auch, dass Sie Lesen schwimmt nur auf die Summe, es gibt keine Notwendigkeit, Sie zu speichern, so
malloc
vermieden werden können, und in der realen Welt überprüfen das Ergebnis derfopen
,fgets
...free()
Lohn, siehe edit.p
Punkte zu Beginn der fileline (und auf jeden iterarion,strtod
ändern Sie diese position zum nächsten Komma in den string)Du bist nicht die Zuweisung von Speicher für die Lohn. Es deklariert einen Zeiger auf einen Zeiger auf einen float; das ist in Ordnung, aber die Zeiger zeigen Sie nicht überall.
Gleiche Sache für ssn.
Nach dieser Zeile:
Müssen Sie Speicher für ssn und Lohn.
Da dies Hausaufgaben, ich werde nicht zu erklären, wie Sie den Speicher; Sie müssen in der Lage sein, es herauszufinden selber.
scanf ("%s", &filename);
ist UB zu.beim zuordnen von Speicher ein Schwimmer Sie müssen verstehen, dass ein float-Wert besteht aus vier bytes, also, wenn Sie rufen malloc braucht es, um dies zu berücksichtigen, zum speichern eines float :
malloc( sizeof(float ) )
zu speichern, ein array der Größe N von floatmalloc( N*sizeof(float ) )
für int ist essizeof(int)