Le code suivant peut être ce que vous cherchez. J'espère que vous n'aurez pas besoin d'une description trop détaillée, mais si vous avez des questions, n'hésitez pas à demander.
Il utilise essentiellement une boucle fgets
pour lire chaque ligne et strtok
pour séparer cette ligne en champs. Il construit une liste chaînée de tableaux entiers qui contiennent les données réelles - vous pouvez voir l'utilisation de cette liste liée dans le code à la fin qui vide la table.
Il a également un moyen par lequel il peut gérer des lignes de taille arbitraire dans le fichier d'entrée sans débordement de tampon (sous réserve de contraintes de mémoire bien sûr). Gardez à l'esprit que le strtok
attend seulement un espace entre chaque champ sur la ligne bien que puisse être recodé pour gérer plusieurs espaces ou même toute quantité d'espace blanc. J'ai gardé ce peu simple puisque le code devenait déjà un peu gros :-)
La fonction atoi
permet de convertir le mot individuel sur chaque ligne en entiers. Si vous voulez vérifier les erreurs, j'appellerais votre propre variante qui vérifie également que tous les caractères du mot sont numériques.
Utilisation de votre fichier d'entrée:
12 3 45 6 7 8
3 5 6 7
7 0 -1 4 5
il produit une sortie le long des lignes de:
0x97b5170, size = 6:
12 3 45 6 7 8
0x97b51d0, size = 4:
3 5 6 7
0x97b51e0, size = 5:
7 0 -1 4 5
Voici le code qui a produit cette sortie:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
// This is the linked list of integer arrays.
typedef struct _tIntArray {
int size;
int *array;
struct _tIntArray *next;
} tIntArray;
static tIntArray *first = NULL;
static tIntArray *last = NULL;
// Add a line of integers as a node.
static int addNode (char *str) {
tIntArray *curr; // pointers for new integer array.
char *word; // word within string.
char *tmpStr; // temp copy of buffer.
int fldCnt; // field count for line.
int i;
// Count number of fields.
if ((tmpStr = strdup (str)) == NULL) {
printf ("Cannot allocate duplicate string (%d).\n", errno);
return 1;
}
fldCnt = 0;
for (word = strtok (tmpStr, " "); word; word = strtok (NULL, " "))
fldCnt++;
free (tmpStr);
// Create new linked list node.
if ((curr = malloc (sizeof (tIntArray))) == NULL) {
printf ("Cannot allocate integer array node (%d).\n", errno);
return 1;
}
curr->size = fldCnt;
if ((curr->array = malloc (fldCnt * sizeof (int))) == NULL) {
printf ("Cannot allocate integer array (%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 (last == NULL)
first = last = curr;
else {
last->next = curr;
last = curr;
}
return 0;
}
int main(void) {
int lineSz; // current line size.
char *buff; // buffer to hold line.
FILE *fin; // input file handle.
long offset; // offset for re-allocating line buffer.
tIntArray *curr; // pointers for new integer array.
int i;
// Open file.
if ((fin = fopen ("qq.in", "r")) == NULL) {
printf ("Cannot open qq.in, errno = %d\n", errno);
return 1;
}
// Allocate initial line.
lineSz = 2;
if ((buff = malloc (lineSz+1)) == NULL) {
printf ("Cannot allocate initial memory, errno = %d.\n", errno);
return 1;
}
// Loop forever.
while (1) {
// Save offset in case we need to re-read.
offset = ftell (fin);
// Get line, exit if end of file.
if (fgets (buff, lineSz, fin) == NULL)
break;
// If no newline, assume buffer wasn't big enough.
if (buff[strlen(buff)-1] != '\n') {
// Get bigger buffer and seek back to line start and retry.
free (buff);
lineSz += 3;
if ((buff = malloc (lineSz+1)) == NULL) {
printf ("Cannot allocate extra memory, errno = %d.\n", errno);
return 1;
}
if (fseek (fin, offset, SEEK_SET) != 0) {
printf ("Cannot seek, errno = %d.\n", errno);
return 1;
}
continue;
}
// Remove newline and process.
buff[strlen(buff)-1] = '\0';
if (addNode (buff) != 0)
return 1;
}
// Dump table for debugging.
for (curr = first; curr != NULL; curr = curr->next) {
printf ("%p, size = %d:\n ", curr, curr->size);
for (i = 0; i < curr->size; i++)
printf (" %d", curr->array[i]);
printf ("\n");
}
// Free resources and exit.
free (buff);
fclose (fin);
return 0;
}
merci pour tous, mais maintenant je me rends compte que le problème est de tokenize. –