简体   繁体   English

如何使用fscanf读取要解析为变量的行?

[英]How to use fscanf to read a line to parse into variables?

I'm trying to read a text file built with the following format in every line, for example: 我正在尝试读取每行以以下格式构建的文本文件,例如:

a/a1.txt
a/b/b1.txt
a/b/c/d/f/d1.txt

Using fscanf to read a line from file, how can you automatically parse the line into the variables of *element and *next , with each element being a path section ( a , a1.txt , b , c , d1.txt and so on). 使用fscanf从文件中读取一行,如何自动将该行解析为*element*next变量,而每个元素都是一个路径部分( aa1.txtbcd1.txt等)。

My structure is as follows: 我的结构如下:

struct MyPath {
    char *element;  // Pointer to the string of one part.
    MyPath *next;   // Pointer to the next part - NULL if none.
}

You would be better off using fgets to read the entire line into memory, then strtok to tokenise the line into individual elements. 您最好使用fgets将整个行读入内存,然后使用strtok将行标记为单个元素。

The following code shows one way to do this. 以下代码显示了执行此操作的一种方法。 First, the headers and structure definintion: 首先,标题和结构定义:

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

typedef struct sMyPath {
    char *element;
    struct sMyPath *next;
} tMyPath;

Then, the main function, initially creating an empty list, then getting input from user (if you want a robust input function, see here , what follows below is a cut down version of that for demonstrative purposes only): 然后,主函数首先创建一个空列表,然后从用户那里获取输入(如果您想要一个健壮的输入函数,请参见此处 ,以下内容仅是出于演示目的的简化版本):

int main(void) {
    char *token;
    tMyPath *curr, *first = NULL, *last = NULL;
    char inputStr[1024];

    // Get a string from the user (removing newline at end).

    printf ("Enter your string: ");
    fgets (inputStr, sizeof (inputStr), stdin);
    if (strlen (inputStr) > 0)
        if (inputStr[strlen (inputStr) - 1] == '\n')
            inputStr[strlen (inputStr) - 1] = '\0';

Then the code to extract all tokens and add them to a linked list. 然后,代码提取所有标记并将它们添加到链接列表中。

    // Collect all tokens into list.

    token = strtok (inputStr, "/");
    while (token != NULL) {
        if (last == NULL) {
            first = last = malloc (sizeof (*first));
            first->element = strdup (token);
            first->next = NULL;
        } else {
            last->next = malloc (sizeof (*last));
            last = last->next;
            last->element = strdup (token);
            last->next = NULL;
        }
        token = strtok (NULL, "/");
    }

(keeping in mind that strdup is not standard C but you can always find a decent implementation somewhere). (请记住, strdup不是标准C,但是您始终可以某处找到不错的实现 )。 Then we print out the linked list to show it was loaded properly, followed by cleanup and exit: 然后,我们打印出链接列表以显示它已正确加载,然后清除并退出:

    // Output list.

    for (curr = first; curr != NULL; curr = curr->next)
        printf ("[%s]\n", curr->element);

    // Delete list and exit.

    while (first != NULL) {
        curr = first;
        first = first->next;
        free (curr->element);
        free (curr);
    }

    return 0;
}

A sample run follows: 运行示例如下:

Enter your string: path/to/your/file.txt
[path]
[to]
[your]
[file.txt]

I should mention also that, while C++ allows you to leave off the struct keyword from structures, C does not. 我还应该提到,尽管C ++允许您从结构中省略struct关键字,但C却不允许。 Your definition should be: 您的定义应为:

struct MyPath {
    char *element;         // Pointer to the string of one part.
    struct MyPath *next;   // Pointer to the next part - NULL if none.
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM