【问题标题】:How to populate a linked list from a file如何从文件中填充链表
【发布时间】:2015-06-24 22:31:01
【问题描述】:

我正在尝试填充从文件中读取的链接列表。我一直在尝试使用strtok() 来分隔使用" " 作为分隔符的字符串。当我调用我的addEntry() 函数时,它只是将每个字符串的第一个字母添加到一个新节点。我意识到这可能是一个简单的疏忽,所以请原谅我的无知,因为我对编码还是很陌生。

我遇到问题的具体代码部分是:

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
    }
}

我的输出只有 16 个节点,每行的第一个字母,当它应该是 96 个节点长时。 我正在读取的文件是:

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

如果需要完整代码:

#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");
}

【问题讨论】:

  • 顺便说一句,strtok_rstrsep 会比 strtok 更好。
  • 谢谢,我现在去查一下文档。
  • 实际上,对于这个特定的问题,由于换行符和空格的处理方式相同,scanf("%ms") 可能是要走的路。
  • 很抱歉,我仍然无法正确实施您的建议。

标签: c linked-list strtok


【解决方案1】:

您需要一个嵌套循环是绝对正确的。

strtok 需要这样调用:

for (char *tok = strtok("input", " "); tok; tok = strtok(NULL, " "))
{
    /* use tok */;
}

【讨论】:

    【解决方案2】:
    • 如果您只对单个字符感兴趣,则无需阅读完整的行(并将它们切割成单个字符)
    • 因为你只对单个字符感兴趣,所以结构中的.data元素不需要是char data[3]
    • 读取文件的函数可以将文件名作为参数
    • 并且该函数可以返回它已读取的列表,而不是返回 void 并将结果通过指针指针传递回调用方。

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

    【讨论】:

    • 数据文件中有一个Qu,如果我没记错的话,Qu加上空字符需要数组char data[3]。不过,我很感谢您的意见。
    • 我故意忽略了u。问题是:如果没有u,是否有可能Q
    • 哈哈,不幸的是,“u”是故意扔在那里的。除了开玩笑,不。
    • 如果在Q之后总是u,那么仍然只有26个令牌。因此,您可以选择在输出时始终在Q 之后附加u
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多