sscanf fails to read string and double seperated by space

Viewed 49

I'm scanning values from a file and storing them in an array. I have a custom struct called NODE which looks like this:

typedef struct node
{
  char *name;
  double value;
  struct node *parent;
  struct node *left_child;
  struct node *right_child;
} NODE;

This function receives a string and two unsigned integer pointers and returns the data that was read in the form of a NODE array:

NODE *readNodes(char filename[], unsigned int *numNodes, unsigned int *capacity)
{
  FILE *f = fopen(filename, "r");
  if (f == NULL)
  {
    exit(1);
  }
  *numNodes = 0;
  *capacity = 1;
  int scanResult;
  char *resultString = NULL;
  char inputString[101];

  NODE *nodes = (NODE *)malloc(sizeof(NODE) * (*capacity));

  while (1)
  {
    while (*numNodes >= *capacity)
    {
      *capacity *= 2;
      nodes = (NODE *)realloc(nodes, sizeof(NODE) * (*capacity));
    }

    resultString = fgets(inputString, 100, f);
    if (resultString == NULL || (strcmp("\n", resultString) == 0))
    {
      break;
    }

    scanResult = sscanf(inputString, "%s %lf", nodes[*numNodes].name, &(nodes[*numNodes].value));
    if (scanResult != 2)
    {
      *numNodes = 0;
      *capacity = 0;
      free(nodes);
      return NULL;
    }

    nodes[*numNodes].parent = NULL;
    nodes[*numNodes].left_child = NULL;
    nodes[*numNodes].right_child = NULL;
    *numNodes++;
  }

  return nodes;
}

The file it's reading from looks like this:

X 0.01
F 0.19
G 0.21
J 1.39
B 1.56
Y 1.96
H 2.08
Z 2.50
P 2.54
C 2.66
U 2.82
M 2.88
D 3.07
K 3.12
V 3.40
R 3.78
T 4.29
L 4.52
S 4.64
N 4.66
I 5.71
E 7.22
O 7.88
A 9.71
0 17.11

I can see from the debugger that it correctly reads a line but the sscanf fails somehow. I tried only scanning the string but that also fails. The return value of the sscanf is always 0 which would mean that it could not scan anything.

This is the full code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct node
{
  char *name;
  double value;
  struct node *parent;
  struct node *left_child;
  struct node *right_child;
} NODE;

typedef struct queue
{
  unsigned int front, end, size;
  unsigned int capacity;
  NODE *array;
} QUEUE;

NODE *readNodes(char filename[], unsigned int *numNodes, unsigned int *capacity)
{
  FILE *f = fopen(filename, "r");
  if (f == NULL)
  {
    exit(1);
  }
  *numNodes = 0;
  *capacity = 1;
  int scanResult;
  char *resultString = NULL;
  char inputString[101];

  NODE *nodes = (NODE *)malloc(sizeof(NODE) * (*capacity));

  while (1)
  {
    while (*numNodes >= *capacity)
    {
      *capacity *= 2;
      nodes = (NODE *)realloc(nodes, sizeof(NODE) * (*capacity));
    }

    resultString = fgets(inputString, 100, f);
    if (resultString == NULL || (strcmp("\n", resultString) == 0))
    {
      break;
    }

    scanResult = sscanf(inputString, "%s %lf", nodes[*numNodes].name, &(nodes[*numNodes].value));
    if (scanResult != 2)
    {
      *numNodes = 0;
      *capacity = 0;
      free(nodes);
      return NULL;
    }

    nodes[*numNodes].parent = NULL;
    nodes[*numNodes].left_child = NULL;
    nodes[*numNodes].right_child = NULL;
    *numNodes++;
  }

  return nodes;
}

int main()
{
  QUEUE freeNodes;
  freeNodes.array = readNodes("./data/input.txt", &(freeNodes.size), &(freeNodes.capacity));
  for (int i = 0; i < freeNodes.size; i++)
  {
    printf("%s\n", freeNodes.array[i].name);
  }
  free(freeNodes.array);
  return 0;
}
0 Answers
Related