要提取的信息如图,这是一个歌曲的标准音高文件。[]内为该句的起始时间和结束时间,<>中的三个数分别为该字相对于句起始时间的起始时间、持续时间和音调。现在要以链表的形式将这个txt中的数据读取出来。
用到的关键函数有:
1)字符串分割函数
char *strtok(char s[],const char *delim);
分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL。
返回值是从s开头开始的一个个被分割的串。当查找不到delim中的字符时,返回NULL。
eg:
#include<string.h>
#include<stdio.h>
int main(void)
{
char input[16]="abc,d";
char*p;
p=strtok(input,",");
if(p)
printf("%s\n",p);
p=strtok(NULL,",");
if(p)
printf("%s\n",p);
return0;
}
结果是打印出abc
d
2)读取一行fgets
char *fgets(char *buf,int bufsize,FILE *stream);
从文件结构体指针stream中读取数据,每次读取一行。读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋’\0’),如果文件中的该行,不足bufsize个字符,则读完该行就结束。如若该行(包括最后一个换行符)的字符数超过bufsize-1,则fgets只返回一个不完整的行,但是,缓冲区总是以NULL字符结尾,对fgets的下一次调用会继续读该行。函数成功将返回buf,失败或读到文件结尾返回NULL。
完整代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 1000
struct singleWord //定义单字处理后的结构
{
double startTime;
double duration;
double pitch;
double word;
singleWord *nextWord;
};
struct singleSentence //定义单句处理后的结构
{
double startTime;
double duration;
singleWord *firstWord;
singleSentence *nextSentence;
};
double charToDouble(char *p) //将读出的字符类型数据转换成int类型
{
double temp=0;
while(*p!='\0')
{
temp+=*p-48;
temp*=10;
p++;
}
temp/=10;
return temp;
}
int main()
{
FILE *fp;
char *inputPath="D:\\wavcs\\我只在乎你.txt";
fp=fopen(inputPath,"r");
if(fp==NULL)
{
printf("can't open this file\n");
exit(0);
}
singleSentence *sentenceHeadNode=(singleSentence *)malloc(sizeof(singleSentence));
singleSentence *qSentence=sentenceHeadNode;
char str[N];
for (int i=0;i<N;i++)
{
str[i]=0;
}
fgets(str,sizeof(str),fp);
char *delim = "[,]<>";
char *p=NULL;
p=strtok(str,delim);
(sentenceHeadNode->startTime)=charToDouble(p);
p=strtok(NULL,delim);
(sentenceHeadNode->duration)=charToDouble(p);
singleWord *wordHeadNode=(singleWord *)malloc(sizeof(singleWord));
singleWord *qWord=wordHeadNode;
qSentence->firstWord=wordHeadNode;
p=strtok(NULL,delim);
(wordHeadNode->startTime)=charToDouble(p);
p=strtok(NULL,delim);
(wordHeadNode->duration)=charToDouble(p);
p=strtok(NULL,delim);
(wordHeadNode->pitch)=charToDouble(p);
p=strtok(NULL,delim);
(wordHeadNode->word)=charToDouble(p);
while(p = strtok(NULL, delim))
{
singleWord *wordNode=(singleWord *)malloc(sizeof(singleWord));
qWord->nextWord=wordNode;
(wordNode->startTime)=charToDouble(p);
p=strtok(NULL,delim);
(wordNode->duration)=charToDouble(p);
p=strtok(NULL,delim);
(wordNode->pitch)=charToDouble(p);
p=strtok(NULL,delim);
(wordHeadNode->word)=charToDouble(p);
qWord=wordNode;
}
qWord->nextWord=NULL;
for (int i=0;i<N;i++)
{
str[i]=0;
}
while (fgets(str,sizeof(str),fp))
{
singleSentence *sentenceNode=(singleSentence *)malloc(sizeof(singleSentence));
qSentence->nextSentence=sentenceNode;
qSentence=sentenceNode;
p=strtok(str,delim);
(sentenceNode->startTime)=charToDouble(p);
p=strtok(NULL,delim);
(sentenceNode->duration)=charToDouble(p);
singleWord *wordHeadNode=(singleWord *)malloc(sizeof(singleWord));
singleWord *qWord=wordHeadNode;
qSentence->firstWord=wordHeadNode;
p=strtok(NULL,delim);
(wordHeadNode->startTime)=charToDouble(p);
p=strtok(NULL,delim);
(wordHeadNode->duration)=charToDouble(p);
p=strtok(NULL,delim);
(wordHeadNode->pitch)=charToDouble(p);
p=strtok(NULL,delim);
(wordHeadNode->word)=charToDouble(p);
while(p = strtok(NULL, delim))
{
singleWord *wordNode=(singleWord *)malloc(sizeof(singleWord));
qWord->nextWord=wordNode;
(wordNode->startTime)=charToDouble(p);
p=strtok(NULL,delim);
(wordNode->duration)=charToDouble(p);
p=strtok(NULL,delim);
(wordNode->pitch)=charToDouble(p);
p=strtok(NULL,delim);
(wordHeadNode->word)=charToDouble(p);
qWord=wordNode;
}
qWord->nextWord=NULL;
for (int i=0;i<N;i++)
{
str[i]=0;
}
}
qSentence->nextSentence=NULL;
singleSentence *sentencePrint=sentenceHeadNode; //读取成链表结构的输出测试
while (sentencePrint!=NULL)
{
printf("%0.0lf ",sentencePrint->startTime);
printf("%0.0lf\n",sentencePrint->duration);
singleWord *wordPrint=sentencePrint->firstWord;
while (wordPrint!=NULL)
{
wordPrint->word=0;
printf("%0.0lf ",wordPrint->startTime);
printf("%0.0lf ",wordPrint->duration);
printf("%0.0lf ",wordPrint->pitch);
printf("%0.0lf ",wordPrint->word);
wordPrint=wordPrint->nextWord;
}
sentencePrint=sentencePrint->nextSentence;
printf("\n\n");
}
fclose(fp);
return 0;
}
输出结果如下图: