2009-09-27 37 views

回答

1

看到我对您的其他问题的回答here。将strtok部分替换为识别非数字字词并且既不增加计数(第一遍)也不会将它们加载到数组(第二遍)中是一件相对简单的事情。

代码已经改变如下:

使用的输入文件:

12 3 45 6 7 8 
3 5 6 7 
7 0 -1 4 5 
12 4 the quick 99 -1 fox dog \ 

它沿着线产生输出:

0x8e42170, size = 6: 
    12 3 45 6 7 8 
0x8e421d0, size = 4: 
    3 5 6 7 
0x8e421e0, size = 5: 
    7 0 -1 4 5 
0x8e42278, size = 4: 
    12 4 99 -1 

下面是产生的输出的代码:

#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; 

// Check that argument is numeric, optional minus sign followed by 
// zero or more digits (you may want one or more). 

static int isAllNumeric (char *word) { 
    char *s = word; 
    if (*s == '-') 
     s++; 
    for (; *s != '\0'; s++) 
     if ((*s < '0') || (*s > '9')) 
      return 0; 
    return 1; 
} 

 

// 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, " ")) 
     if (isAllNumeric (word)) 
      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, " ")) 
     if (isAllNumeric (word)) 
      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; 
}