1

I am trying to populate a linked list reading in from a file. I have been attempting to use strtok() to break apart a string using " " as a delimiter. When I call my addEntry() function it is only adding the first letter of each string to a new node. I realize this is probably a simple oversight, so please excuse my ignorance as I am still quite new to coding.

The specific section of code I am having trouble with is:

void readData(struct boggleDataNode **headRef){
    //initializing variables including
    //opening the input file
    int counter = 96;
    int i = 0;
    char dataLine[LENGTH];
    char *data;
    char *fileName = "BoggleData.txt";
    FILE *filePointer;

    printf("Trying to open file %s\n", fileName);
    filePointer = fopen(fileName, "r"); //read mode
    printf("Successfully opened file %s\n", fileName);

    if (filePointer == NULL){
        perror("Error while opening file. \n");
        exit(0);
    }

    //loop until find end of file
    while ( fgets(dataLine, LENGTH, filePointer) != NULL){
        //I feel like i should be using a nested loop here but I can't figure out how to do it 
        printf("dataLine = %s\n", dataLine);
        data = strtok(dataLine, " ");
        printf("data = %s\n", data);
        //fgets(data, 3, filePointer);
        addEntry(headRef, data);
        //nested loop should end here
    }
}

My output is only 16 nodes, the first letter from each line, when it should be 96 nodes long. The file which I am reading from is:

D R L X E I
C P O H S A
N H N L Z R
W T O O T A
I O S S E T
N W E G H E
B O O J A B
U I E N E S
P S A F K F
I U N H M Qu
Y R D V E L
V E H W H R
I O T M U C
T Y E L T R
S T I T Y D
A G A E E N

In case the full code is needed:

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

#define LENGTH 80

struct boggleDataNode {
    char data[3];
    struct boggleDataNode *nextData;
};

struct boggleDieSideNode {
    char dieSideData[3];
    struct boggleDieSideNode *nextSide;
};

void readData(struct boggleDataNode **);
void addEntry(struct boggleDataNode **, char *);
void display(struct boggleDataNode *);

int main() {

    int counter = 0;

    struct boggleDataNode * head = NULL;
    struct boggleDieSideNode *head1 = NULL;
    readData(&head);
    display(head);

    system("pause");
    return 0;
}

void readData(struct boggleDataNode **headRef){
    //initializing variables including
    //opening the input file
    int counter = 96;
    int i = 0;
    char dataLine[LENGTH];
    char *data;
    char *fileName = "BoggleData.txt";
    FILE *filePointer;

    printf("Trying to open file %s\n", fileName);
    filePointer = fopen(fileName, "r"); //read mode
    printf("Successfully opened file %s\n", fileName);

    if (filePointer == NULL){
        perror("Error while opening file. \n");
        exit(0);
    }

    //loop until find end of file
    while ( fgets(dataLine, LENGTH, filePointer) != NULL){
        printf("dataLine = %s\n", dataLine);
        data = strtok(dataLine, " ");
        printf("data = %s\n", data);
        //fgets(data, 3, filePointer);
        addEntry(headRef, data);
    }

    fclose(filePointer);

}//cose readData

void addEntry(struct boggleDataNode **headRef, char *data){

    //allocate node
    struct boggleDataNode* temp = (struct boggleDataNode*) malloc(sizeof(struct boggleDataNode));

    //put in data
    strcpy(temp->data, data);

    // link the old list off the new node
    temp->nextData = (*headRef);

    // move the head to point to the new node
    (*headRef) = temp;
}

void display(struct boggleDataNode *headRef){

    struct boggleDataNode *helper = headRef;

    if (helper == NULL){
        return;
    }
    else{
        printf("============================================\n");
        printf("Node #        Data\n");
        printf("============================================\n");

        int counter = 1;

        while (helper != NULL){
            printf("%5d \t %2s\n", counter++, helper->data);
            helper = helper->nextData;
        }
    }
    printf("\n");
    system("pause");
}
4
  • Btw, strtok_r or strsep would be better than strtok. Commented Jun 24, 2015 at 22:35
  • Thank you, I will look up the documentation for it now. Commented Jun 24, 2015 at 22:38
  • Actually, for this specific problem, since newlines and spaces are treated identically, scanf("%ms") might be the way to go. Commented Jun 24, 2015 at 22:49
  • I'm sorry I'm still having trouble implementing your suggestion properly. Commented Jun 24, 2015 at 22:58

2 Answers 2

1

You are absolutely correct that you need a nested loop.

strtok needs to be called like this:

for (char *tok = strtok("input", " "); tok; tok = strtok(NULL, " "))
{
    /* use tok */;
}
Sign up to request clarification or add additional context in comments.

Comments

0
  • if you are only interested in single characters there is no need to read complete lines (and cut them into single characters)
  • since you are only interested in single characters, the .data element in the structure does not need to be char data[3]
  • a function that reads a file could take the filename as an argument
  • and the function could return the list it has read, instead of returning void and passing the result back to the caller via a pointer-to-pointer.

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

struct boggleNode {
    struct boggleNode *next;
    char data;
    };

struct boggleNode * readboggle(char *name);

int main (int argc, char **argv)
{
struct boggleNode *bp;

if (!argv[1]) return 0;

bp = readboggle( argv[1] );

for ( ; bp; bp = bp-> next) {
        printf(" %c", bp->data);
        }

printf("\n" );
return 0;
}

struct boggleNode * readboggle(char *name)
{
struct boggleNode *ret=NULL, **bpp;
FILE *fp;
int ch;

fp = fopen (name, "r" );
if (!fp) return NULL;

ret= NULL;
bpp = &ret;
while(1)        {
        ch = getc(fp);
        if (ch == EOF) break;
        if (ch < 'A' || ch > 'Z') continue;
        *bpp = malloc (sizeof **bpp);
        (*bpp)->data = ch;
        (*bpp)->next = NULL;
        bpp = &(*bpp)->next;
        }
fclose (fp);
return ret;
}

4 Comments

There is a Qu in the data file, the Qu plus the null character requires the array char data[3] if I'm not mistaken. I appreciate the input though.
I purposely ignored the u. Question is: is there a Q possible without the u ?
Haha, unfortunately the "u" was thrown in there on purpose. And all joking aside, no.
If there always is a u after a Q, then there still are only 26 tokens. So you could choose to always append a u after a Q when outputting.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.