Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C中忽略txt文件的特定部分_C_File_Struct_Txt - Fatal编程技术网

如何在C中忽略txt文件的特定部分

如何在C中忽略txt文件的特定部分,c,file,struct,txt,C,File,Struct,Txt,我的问题是,是否可以使用fscanf()忽略稍后存储在结构中的txt文件的特定部分。 在本例中,我假设我有一个由以下文本组成的txt文件: Title: C Programming Language Author: Dennis Ritchie Publication year: 1978 ... 我想将数据存储在这样的结构中,忽略标题:,作者:,出版年份:等等: struct book { char title[MAX]; char author[MAX]; int

我的问题是,是否可以使用
fscanf()
忽略稍后存储在结构中的txt文件的特定部分。 在本例中,我假设我有一个由以下文本组成的txt文件:

Title: C Programming Language
Author: Dennis Ritchie
Publication year: 1978
...
我想将数据存储在这样的结构中,忽略
标题:
作者:
出版年份:
等等:

struct book {
    char title[MAX];
    char author[MAX];
    int pubblication_year;
    ...
};
这是我为存储数据而实现的代码:

fscanf(fp, "%[^\n]%*c\n", newOne->books.title);  //titolo
fscanf(fp, "%[^\n]%*c\n", newOne->books.author); //autore
fscanf(fp, "%d\n", &newOne->books.pubblication_year); //anno pubblicazione
...
这里有一个简单的例子:

#include <stdio.h>
#include <stdlib.h>
#define MAX 30
struct book {
    char title[MAX];
    char author[MAX];
};

struct booklist {
    struct book books;
    struct booklist *next;
};


int main() {
    struct booklist *head = NULL, *newOne, *temp; //temp made in order to clear the heap once the program is termined
    FILE *fp;
    fp = fopen("FileName.txt", "r");
    if(fp == NULL) {
    printf("Something wrong happened, the program will close!\n");
        system("pause");
        exit(1);
    } else {
        newOne = (struct booklist *)malloc(sizeof(struct booklist));
        if(newOne == NULL) {
            printf("Error, not enough space to store the new book, the program will close!\n");
                   system("Pause");
                   exit(1);
        }
        fscanf(fp, "%[^\n]%*c\n", newOne->books.title);  //ADDING THE TITLE TO THE NODE
        fscanf(fp, "%[^\n]%*c\n", newOne->books.author); //SAME FOR THE AUTHOR

        //adding the new one node created to the head of the list
        newOne->next = head;
        head = newOne;
    }
    while (newOne != NULL) { //cleaning the heap once the program is termined
    temp = newOne;
    newOne = newOne -> next;
    free(temp);
    }
    fclose(fp);
    return 0;
}

#包括
#包括
#定义最大值30
结构书{
字符标题[MAX];
字符作者[MAX];
};
结构书单{
结构书;
结构图书列表*下一步;
};
int main(){
struct booklist*head=NULL,*newOne,*temp;//创建temp是为了在程序终止后清除堆
文件*fp;
fp=fopen(“FileName.txt”,“r”);
如果(fp==NULL){
printf(“发生错误,程序将关闭!\n”);
系统(“暂停”);
出口(1);
}否则{
newOne=(struct booklist*)malloc(sizeof(struct booklist));
if(newOne==NULL){
printf(“错误,没有足够的空间存储新书,程序将关闭!\n”);
系统(“暂停”);
出口(1);
}
fscanf(fp,“%[^\n]%*c\n”,newOne->books.title);//将标题添加到节点
fscanf(fp,“%[^\n]%*c\n”,newOne->books.author);//作者也一样
//将创建的新节点添加到列表的头部
新建->下一个=头部;
头=新的;
}
while(newOne!=NULL){//程序终止后清理堆
温度=新的;
新建一个=新建一个->下一个;
免费(临时);
}
fclose(fp);
返回0;
}

是否可以这样做?

使用
fscanf

char str[] = "Title: C Programming Language";
int len1 = strlen(str); // find length of str

char ch = ':';
char *ret;

ret = strchr(str, ch); // ret points to ---> : C Programming Language
int len2 = strlen(ret);

fseek(fp, (len1-len2), SEEK_SET); // move file pointer
fscanf(fp, "%[^\n]%*c", newOne->books.title);
不使用
fscanf

char str[] = "Title: C Programming Language";
int len1 = strlen(str); // find length of str

char ch = ':';
char *ret;

ret = strchr(str, ch); // ret points to ---> : C Programming Language
int len2 = strlen(ret);

fseek(fp, (len1-len2), SEEK_SET); // move file pointer
fscanf(fp, "%[^\n]%*c", newOne->books.title);
只需使用
strchr()
函数即可

char str[] = "Title: C Programming Language";
char ch = ':';
char *ret;

ret = strchr(str, ch); 
printf("%s", ret+1) // prints C Programming Language

使用
fscanf

char str[] = "Title: C Programming Language";
int len1 = strlen(str); // find length of str

char ch = ':';
char *ret;

ret = strchr(str, ch); // ret points to ---> : C Programming Language
int len2 = strlen(ret);

fseek(fp, (len1-len2), SEEK_SET); // move file pointer
fscanf(fp, "%[^\n]%*c", newOne->books.title);
不使用
fscanf

char str[] = "Title: C Programming Language";
int len1 = strlen(str); // find length of str

char ch = ':';
char *ret;

ret = strchr(str, ch); // ret points to ---> : C Programming Language
int len2 = strlen(ret);

fseek(fp, (len1-len2), SEEK_SET); // move file pointer
fscanf(fp, "%[^\n]%*c", newOne->books.title);
只需使用
strchr()
函数即可

char str[] = "Title: C Programming Language";
char ch = ':';
char *ret;

ret = strchr(str, ch); 
printf("%s", ret+1) // prints C Programming Language

有几种方法可以使用格式字符串来实现此目的。这是一个完全可行的选择。但最简单的方法可能是这样的:

fscanf(fp, "%[^\n]%*c\n", newOne->books.title);
char remove[] = "Title: ";
size_t size = sizeof (remove);
char *s = newOne->books.title;
memove(s, s[size], size);
#include <stdio.h>
#include <stdlib.h>

#define xstr(s) str(s)
#define str(s) #s

#define MAX 30
struct book {
    char title[MAX + 1];
    char author[MAX + 1];
};

struct booklist {
    struct book books;
    struct booklist *next;
};
struct booklist *new_booklist(void)
{
    struct booklist *newOne = malloc(sizeof(struct booklist));
    if (newOne == NULL) {
        printf("Error, not enough space to store the new book, the program will close!\n");
        exit(1);
    }
    return newOne;
}
void booklist_add(struct booklist **head, struct booklist *newOne)
{
    newOne->next = *head;
    *head = newOne;
}
void booklist_delete_list(struct booklist **head)
{
    struct booklist *cur = *head;
    while (cur != NULL) {
        struct booklist *temp = cur;
        cur = cur->next;
        free(temp);
    }
    *head = NULL;
}

int main(void)
{
    struct booklist *head = NULL; 
    
    FILE *fp = fopen("input.txt", "r");
    if (fp == NULL) {
        printf("Something wrong happened, the program will close!\n");
        exit(1);
    }

    while(1) {
        struct booklist *tmp = new_booklist();

        int n = 0;
        n += fscanf(fp, " Title: %" xstr(MAX) "[^\n]", tmp->books.title);
        n += fscanf(fp, " Author: %" xstr(MAX) "[^\n]", tmp->books.author);

        if (n != 2) {
            free(tmp);
            break;
        }

        booklist_add(&head, tmp);
    }

    booklist_delete_list(&head);

    fclose(fp);
    return 0;
}

没有测试上面的代码。可能是小错误。

有几种方法可以使用格式字符串。这是一个完全可行的选择。但最简单的方法可能是这样的:

fscanf(fp, "%[^\n]%*c\n", newOne->books.title);
char remove[] = "Title: ";
size_t size = sizeof (remove);
char *s = newOne->books.title;
memove(s, s[size], size);
#include <stdio.h>
#include <stdlib.h>

#define xstr(s) str(s)
#define str(s) #s

#define MAX 30
struct book {
    char title[MAX + 1];
    char author[MAX + 1];
};

struct booklist {
    struct book books;
    struct booklist *next;
};
struct booklist *new_booklist(void)
{
    struct booklist *newOne = malloc(sizeof(struct booklist));
    if (newOne == NULL) {
        printf("Error, not enough space to store the new book, the program will close!\n");
        exit(1);
    }
    return newOne;
}
void booklist_add(struct booklist **head, struct booklist *newOne)
{
    newOne->next = *head;
    *head = newOne;
}
void booklist_delete_list(struct booklist **head)
{
    struct booklist *cur = *head;
    while (cur != NULL) {
        struct booklist *temp = cur;
        cur = cur->next;
        free(temp);
    }
    *head = NULL;
}

int main(void)
{
    struct booklist *head = NULL; 
    
    FILE *fp = fopen("input.txt", "r");
    if (fp == NULL) {
        printf("Something wrong happened, the program will close!\n");
        exit(1);
    }

    while(1) {
        struct booklist *tmp = new_booklist();

        int n = 0;
        n += fscanf(fp, " Title: %" xstr(MAX) "[^\n]", tmp->books.title);
        n += fscanf(fp, " Author: %" xstr(MAX) "[^\n]", tmp->books.author);

        if (n != 2) {
            free(tmp);
            break;
        }

        booklist_add(&head, tmp);
    }

    booklist_delete_list(&head);

    fclose(fp);
    return 0;
}

没有测试上面的代码。可能是小错误。

您的问题是您没有清楚地定义您希望程序执行的操作

首先,你应该清楚地说明你的目标。给定此文件:

Title: C Programming Language
Author: Dennis Ritchie

Title: The Lord of the Rings
Author: John Ronald Reuel Tolkien

Title: War and Peace
Author: Leo Tolstoy
它应该读“C编程语言”和“丹尼斯·里奇”,然后是其他。但是“标题:”后面的空格是强制性的吗?可以有多个空间吗?标题和作者之间可以有“空”行吗?必须有“头衔:”吗?“作者”能在“标题”之前吗?等等定义了所有这些之后,就有了一个文件格式,也许可以用fscanf对其进行解析

在这种情况下,如果格式为

<0 or more whitespaces> Title: <0 or more whitespaces> <anything but newline> <newline>
要求在标题之前出现字符
标题:
。如果缺少这些,它将失败

然后,由于缓冲区的大小有限(这是一个非常糟糕的主意),建议限制
fscanf()
将尝试放入变量的最大字符数(我假设您有一个31个字符的数组):

用宏来做这件事很痛苦,但它是可以做到的。因此,您可以像这样读取该文件:

fscanf(fp, "%[^\n]%*c\n", newOne->books.title);
char remove[] = "Title: ";
size_t size = sizeof (remove);
char *s = newOne->books.title;
memove(s, s[size], size);
#include <stdio.h>
#include <stdlib.h>

#define xstr(s) str(s)
#define str(s) #s

#define MAX 30
struct book {
    char title[MAX + 1];
    char author[MAX + 1];
};

struct booklist {
    struct book books;
    struct booklist *next;
};
struct booklist *new_booklist(void)
{
    struct booklist *newOne = malloc(sizeof(struct booklist));
    if (newOne == NULL) {
        printf("Error, not enough space to store the new book, the program will close!\n");
        exit(1);
    }
    return newOne;
}
void booklist_add(struct booklist **head, struct booklist *newOne)
{
    newOne->next = *head;
    *head = newOne;
}
void booklist_delete_list(struct booklist **head)
{
    struct booklist *cur = *head;
    while (cur != NULL) {
        struct booklist *temp = cur;
        cur = cur->next;
        free(temp);
    }
    *head = NULL;
}

int main(void)
{
    struct booklist *head = NULL; 
    
    FILE *fp = fopen("input.txt", "r");
    if (fp == NULL) {
        printf("Something wrong happened, the program will close!\n");
        exit(1);
    }

    while(1) {
        struct booklist *tmp = new_booklist();

        int n = 0;
        n += fscanf(fp, " Title: %" xstr(MAX) "[^\n]", tmp->books.title);
        n += fscanf(fp, " Author: %" xstr(MAX) "[^\n]", tmp->books.author);

        if (n != 2) {
            free(tmp);
            break;
        }

        booklist_add(&head, tmp);
    }

    booklist_delete_list(&head);

    fclose(fp);
    return 0;
}
#包括
#包括
#定义xstr(s)str(s)
#定义str(s)#s
#定义最大值30
结构书{
字符标题[MAX+1];
字符作者[MAX+1];
};
结构书单{
结构书;
结构图书列表*下一步;
};
结构书目*新建书目(无效)
{
struct booklist*newOne=malloc(sizeof(struct booklist));
if(newOne==NULL){
printf(“错误,没有足够的空间存储新书,程序将关闭!\n”);
出口(1);
}
返回newOne;
}
作废书目\添加(结构书目**表头,结构书目*新建)
{
新建->下一步=*头部;
*头=新的;
}
作废账簿列表\删除\列表(结构账簿列表**标题)
{
结构图书清单*cur=*表头;
while(cur!=NULL){
结构图书清单*temp=cur;
cur=cur->next;
免费(临时);
}
*head=NULL;
}
内部主(空)
{
struct booklist*head=NULL;
文件*fp=fopen(“input.txt”,“r”);
如果(fp==NULL){
printf(“发生错误,程序将关闭!\n”);
出口(1);
}
而(1){
struct booklist*tmp=new_booklist();
int n=0;
n+=fscanf(fp,“Title:%”“xstr(MAX)”[^\n]”,tmp->books.Title);
n+=fscanf(fp,“Author:%”“xstr(MAX)”[^\n]”,tmp->books.Author);
如果(n!=2){
免费(tmp);
打破
}
书目\添加(tmp标题和标题);
}
图书列表\删除\列表(&head);
fclose(fp);
返回0;
}

好吧,也许最好将
sprintf()
转换为一个格式变量,并将其用作格式字符串,但我不喜欢这两种解决方案中的任何一种。最好的方法可能是使用POSIX之类的工具。您的问题是,您没有清楚地定义您希望程序执行的操作

首先,你应该清楚地说明你的目标。给定此文件:

Title: C Programming Language
Author: Dennis Ritchie

Title: The Lord of the Rings
Author: John Ronald Reuel Tolkien

Title: War and Peace
Author: Leo Tolstoy
它应该读“C编程语言”和“丹尼斯·里奇”,然后是其他。但是“标题:”后面的空格是强制性的吗?可以有多个空间吗?标题和作者之间可以有“空”行吗?必须有“头衔:”吗?“作者”能在“标题”之前吗?等等定义了所有这些之后,就有了一个文件格式,也许可以用fscanf对其进行解析

在这种情况下,如果格式为

<0 or more whitespaces> Title: <0 or more whitespaces> <anything but newline> <newline>
要求字符
标题: