Der folgende Code könnte das sein, wonach Sie suchen. Hoffentlich benötigen Sie nicht zu viel Erklärung, da Kommentare vorhanden sind, aber wenn Sie Fragen haben, zögern Sie nicht, zu fragen.
Es verwendet im Grunde eine Schleife mit fgets
, um jede Zeile einzulesen und strtok
, um diese Zeile in Felder zu trennen. Es konstruiert eine verkettete Liste von Integer-Arrays, die die tatsächlichen Daten enthalten - Sie können die Verwendung dieser verketteten Liste im Code am Ende sehen, der die Tabelle ausgibt.
Es bietet auch eine Möglichkeit, beliebig große Zeilen in der Eingabedatei ohne Pufferüberlauf zu verarbeiten (abhängig von Speicherbeschränkungen). Beachten Sie, dass das strtok
nur ein Leerzeichen zwischen jedem Feld auf der Zeile erwartet, obwohl dies so umprogrammiert werden könnte, dass es auch mehrere Leerzeichen oder sogar beliebige Mengen an Leerzeichen handhabt. Ich habe diesen Teil einfach gehalten, da der Code bereits ein wenig groß war :-)
Die Funktion atoi
wird verwendet, um das einzelne Wort auf jeder Zeile in Integer umzuwandeln. Wenn Sie eine Fehlerüberprüfung für diese wünschen, würde ich Ihre eigene Variante aufrufen, die auch überprüft, ob alle Zeichen im Wort numerisch sind.
Bei Verwendung Ihrer Eingabedatei:
12 3 45 6 7 8
3 5 6 7
7 0 -1 4 5
erzeugt es eine Ausgabe in etwa wie folgt:
0x97b5170, Größe = 6:
12 3 45 6 7 8
0x97b51d0, Größe = 4:
3 5 6 7
0x97b51e0, Größe = 5:
7 0 -1 4 5
Hier ist der Code, der diese Ausgabe produziert hat:
#include
#include
#include
#include
// Hierbei handelt es sich um die verkettete Liste von Integer-Arrays.
typedef struct _tIntArray {
int size;
int *array;
struct _tIntArray *next;
} tIntArray;
static tIntArray *erste = NULL;
static tIntArray *letzte = NULL;
// Füge eine Zeile von Ganzzahlen als Knoten hinzu.
static int addNode (char *str) {
tIntArray *curr; // Zeiger für neues Integer-Array.
char *word; // Wort innerhalb des Strings.
char *tmpStr; // Temporäre Kopie des Puffers.
int fldCnt; // Feldanzahl für Zeile.
int i;
// Zähle die Anzahl der Felder.
if ((tmpStr = strdup (str)) == NULL) {
printf ("Kann keinen duplizierten String erstellen (%d).\n", errno);
return 1;
}
fldCnt = 0;
for (word = strtok (tmpStr, " "); word; word = strtok (NULL, " "))
fldCnt++;
free (tmpStr);
// Erstelle neuen Knoten für die verkettete Liste.
if ((curr = malloc (sizeof (tIntArray))) == NULL) {
printf ("Kann keinen Integer-Array-Knoten zuweisen (%d).\n", errno);
return 1;
}
curr->size = fldCnt;
if ((curr->array = malloc (fldCnt * sizeof (int))) == NULL) {
printf ("Kann keinen Integer-Array zuweisen (%d).\n", errno);
free (curr);
return 1;
}
curr->next = NULL;
for (i = 0, word = strtok (str, " "); word; word = strtok (NULL, " "))
curr->array[i++] = atoi (word);
if (letzte == NULL)
erste = letzte = curr;
else {
letzte->next = curr;
letzte = curr;
}
return 0;
}
int main(void) {
int lineSz; // Aktuelle Zeilengröße.
char *buff; // Puffer zum Halten der Zeile.
FILE *fin; // Datei-Handle für Eingabedatei.
long offset; // Offset zum Neuzuweisen des Zeilenpuffers.
tIntArray *curr; // Zeiger für neues Integer-Array.
int i;
// Öffne Datei.
if ((fin = fopen ("qq.in", "r")) == NULL) {
printf ("Kann qq.in nicht öffnen, errno = %d\n", errno);
return 1;
}
// Weise Anfangspuffer zu.
lineSz = 2;
if ((buff = malloc (lineSz+1)) == NULL) {
printf ("Kann keinen anfänglichen Speicher zuweisen, errno = %d.\n", errno);
return 1;
}
// Schleife unbegrenzt.
while (1) {
// Speichere Offset, falls erforderlich.
offset = ftell (fin);
// Hole Zeile, beende bei Dateiende.
if (fgets (buff, lineSz, fin) == NULL)
break;
// Wenn kein Zeilenumbruch vorhanden, gehe davon aus, dass der Puffer nicht groß genug war.
if (buff[strlen(buff)-1] != '\n') {
// Hole größeren Puffer, setze zurück zum Anfang der Zeile und versuche erneut.
free (buff);
lineSz += 3;
if ((buff = malloc (lineSz+1)) == NULL) {
printf ("Kann keinen zusätzlichen Speicher zuweisen, errno = %d.\n", errno);
return 1;
}
if (fseek (fin, offset, SEEK_SET) != 0) {
printf ("Kann nicht suchen, errno = %d.\n", errno);
return 1;
}
continue;
}
// Entferne Zeilenumbruch und verarbeite.
buff[strlen(buff)-1] = '\0';
if (addNode (buff) != 0)
return 1;
}
// Tabelle für Debugging ausgeben.
for (curr = erste; curr != NULL; curr = curr->next) {
printf ("%p, Größe = %d:\n ", curr, curr->size);
for (i = 0; i < curr->size; i++)
printf (" %d", curr->array[i]);
printf ("\n");
}
// Ressourcen freigeben und beenden.
free (buff);
fclose (fin);
return 0;
}
0 Stimmen
Danke für alles, aber jetzt erkenne ich, dass das Problem darin besteht, zu tokenisieren.