我想弄清楚为什么使用C函数strtok
对我不起作用。这是问题所在:
我有一个文件,其中包含两种类型的信息:标题和文本说明。文件中的每一行都是标题或文本描述的一部分。标头以“>”开头。描述文本在标题后面,可以跨越多行。在文本的末尾有一个空行,用于将描述与下一个标题分开。我的目标是编写两个单独的文件:一个包含每行的标题,另一个包含一行的相应描述。为了在C中实现代码,我使用fgets
一次一行地将文件读入动态分配的内存。为了在一行中编写描述文本,我使用`strtok来删除文本中存在的任何新行字符。
我的代码适用于头文件。但是,对于描述文件,我注意到文本的最后一个字符未打印到文件,即使它已打印到标准输出。
FILE *headerFile = fopen("Headers", "w"); //to write headers
FILE *desFile = fopen("Descriptions", "w"); //to write descriptions
FILE *pfile = fopen("Data","r");
if ( pfile != NULL )
{
int numOfHeaders =0;
char **data1 = NULL; //an array to hold a header line
char **data2 = NULL; //an array to hold a description line
char line[700] ; //maximum size for the line
while (fgets(line, sizeof line, pfile ))
{
if(line[0] =='>') //It is a header
{
data1 = realloc(data1,(numOfHeaders +1)* sizeof(*data1));
data1[numOfHeaders]= malloc(strlen(line)+1);
strcpy(data1[numOfHeaders],line);
fprintf(headerFile, "%s",line);//writes the header
if(numOfHeaders >0)
fprintf(desFile, "\n");//writes a new line in the desc file
numOfHeaders++;
}
//it is not a header and not an empty line
if(line[0] != '>' && strlen(line)>2)
{
data2 = realloc(data2,(numOfHeaders +1)* sizeof(*data2));
data2[numOfHeaders]= malloc(strlen(line)+1);
char *s = strtok(line, "\n ");
strcpy(data2[numOfHeaders],s);
fprintf(desFile, "%s",data2[numOfHeaders]);
printf(desFile, "%s",data2[numOfHeaders]);
}
} //end-while
fclose(desFile);
fclose(headerFile);
fclose(pfile );
printf("There are %d headers in the file.\n",numOfHeaders);
}
答案 0 :(得分:0)
如评论中所述:
fprintf(desFile, "%s",data2[numOfHeaders]); //okay
printf(desFile, "%s",data2[numOfHeaders]); //wrong
第二行应该是:
printf("%s",data2[numOfHeaders]); //okay
或者,你可以这样做:
sprintf(buffer, "%s",data2[numOfHeaders]);
fprintf(desFile, buffer);
printf(buffer);
其他可能的问题 :
如果没有输入文件,就无法确定strtok()
正在做什么,但这是根据您所描述的内容进行的猜测:
在这两行中 :
data2[numOfHeaders]= malloc(strlen(line)+1);
char *s = strtok(line, "\n ");
如果data2中包含的字符串包含任何嵌入空格, s 将仅包含在该空格之前出现的段。并且因为您只是在 行 刷新之前只调用一次:
while (fgets(line, sizeof line, pfile ))
只会读取一个令牌(第一个段)。
并非总是如此,但 通常 ,在循环中调用strtok()
:
char *s = {0};
s= strtok(stringToParse, "\n ");//make initial call before entering loop
while(s)//ALWAYS test to see if s contains new content, else NULL
{
//do something with s
strcpy(data2[numOfHeaders],s);
//get next token from string
s = strtok(NULL, "\n ");//continue to tokenize string until s is null
}
但是,正如我上面所说,在字符串的内容发生变化之前,你只在该字符串上调用一次。那么,有可能strtok()
尚未对尚未打印的段进行标记化。