如何在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>
此要求字符标题: