学习c如何将strtok中的位置指针设为int
这里的初学者, 对练习有点困惑: 页面上的最后一个(是德语)。我应该阅读HTML行并打印属性及其值。给出了应该使用的函数的声明。学习c如何将strtok中的位置指针设为int,c,string,strtok,C,String,Strtok,这里的初学者, 对练习有点困惑: 页面上的最后一个(是德语)。我应该阅读HTML行并打印属性及其值。给出了应该使用的函数的声明。 有两件事让我恼火: 1.该行存储在一个const char字符串中,但我希望用户输入所需的HTML行。似乎不可能在运行时更改常量变量。如何在不更改给定声明的情况下实现此目标? 2.教程想让我把strtok搜索的位置作为一个整数返回,但我在网上读到这个值存储在strtok中,有没有办法转换它,或者以某种方式获得它 为了解决这个问题,我写了这段代码,但是程序在运行时崩溃了
有两件事让我恼火:
1.该行存储在一个const char字符串中,但我希望用户输入所需的HTML行。似乎不可能在运行时更改常量变量。如何在不更改给定声明的情况下实现此目标?
2.教程想让我把strtok搜索的位置作为一个整数返回,但我在网上读到这个值存储在strtok中,有没有办法转换它,或者以某种方式获得它 为了解决这个问题,我写了这段代码,但是程序在运行时崩溃了,出现了“分段错误(内核转储)”-消息,我不知道为什么,有人能给我解释一下吗?(我可能需要malloc,但对于哪个变量?)
//cHowTo Uebung Teil 2第4号
//HTMLine.c
#包括
#包括
#包括
//char-gethtmline();
int getHtmlatAttributes(const char*string,int start,char*attrNamem,char*attrValue)//由教程给出
int main(int argc,char*argv)//因为如果可能的话,我希望稍后用户输入
{
const char strg[]={”“};//按教程给出了示例行
char attriN[255]={0},attriV[255]={0};
int pos=99;
//printf(“请键入标签进行分析。\n”);
//fgets(标准零售价,255,标准零售价);
printf(“属性\t值\n\n”);
做
{
pos=getHtmlatAttributes(strg,pos,attriN,attriV);//pos应该是strtok搜索位置
printf(“%s\t\t%s\n”,attriN,attriV);
}
while(pos!=1);
返回退出成功;
}
int getHtmlatAttributes(常量char*string,int start,char*attrNamem,char*attrValue)
{
int i,len;
char*ptr;
len=strlen(字符串);
char stringT[len];//用于由strtok拆分的变量
对于(i=0;i而言,strtok()
所做的是,如果使用与NULL
不同的字符串调用它,它会在内部存储指向该字符串的指针并返回第一个标记。随后使用NULL
调用它,然后使用该内部存储的指针确定下一个标记
现在,代码中发生的是:
当您第一次调用getHtmlAttributes()
时,您将在stringT
中创建给定string
的副本,并将该副本传递给strtok()
。下次调用strtok(NULL,…)
。我们有两个错误:
将string()
复制到stringT()
的循环不正确。您没有复制
终止符'\0'
。在这种情况下只需使用strcpy()
重要的一点是:当您第二次调用getHtmlAttributes()
时,您调用了strtok(NULL,…)
,但是最初调用它的stringT
的生存期随着getHtmlAttributes()的第一次调用而结束
返回,因为stringT
是一个局部变量,每次调用函数时都会在堆栈上重新创建。您可以通过
- 声明
静态字符字符串[N]
其中N必须是常数(如255),在这种情况下不能使用len
(无论如何应该是len+1
)
- 通过
char*stringT=strdup(string);
创建动态分配的string
副本。请仅在以后调用strtok(stringT,…)
时执行此操作,并且请注意,如果没有其他代码,则会出现内存泄漏,因为无法再次释放该内存
- 我建议:直接使用
string
而不是stringT
。在这种情况下,您不应该将string
声明为const,并在main()
中创建传递给函数的strg
副本
编辑
我认为“将strtok search的位置作为整数返回”的请求意味着,您应该在完整字符串中返回找到的标记的偏移量。如果您从上面使用建议的解决方案static char stringT[N]
,这很容易实现:
由于strtok()
作用于第一次调用传递的字符串,因此在接收到与NULL不同的ptr
后,您可以计算并返回int offset=ptr-stringT;
编辑2
现在完全不同了
我刚刚阅读了您链接到的教程(Hessen的问候语:-),我认为这个想法是在每次调用函数时都使用一个新的strtok()
循环。可能是这样的:
int getHtmlAttributes(const char *string, int start, char *attrName, char *attrValue)
{
char *buf;
char *attrptr;
char *ptr;
// copy the substring starting at start to buf
// you should add error checking (buf may become NULL)
buf = strdup( string+start );
// first step: tokenize on whitespace; we stop at the first token that contains a "="
for( attrptr = strtok( buf, " \t" ); attrptr && (ptr = strchr( attrptr, '=' )) != NULL; attrptr = strtok( NULL, " \t" ) ) ;
if( attrptr ) {
// copy everything before "=" to attrName
sprintf( attrName, "%.*s", ptr-attrptr, attrptr );
// copy everything after "=" to attrValue
strcpy( attrValue, ptr+1 );
// the next start is the current start + the offset of the attr found
// + the length of the complete attr
start += (attrptr - buf) + strlen( attrptr );
free( buf );
return start;
} else {
// no more attribute
free( buf );
return -1;
}
}
在调试器中运行它,或者加入一些printf()来缩小崩溃的范围。您需要为返回的attrName
s和attrValue
s分配内存。返回到关于数组和/或char*
样式字符串的教程页面,然后重新阅读:)我以为会有(足够)使用char attriN[255]={0},attriV[255]={0};
保留的内存感谢您的回答。我现在正确地从string
复制到stringT
。因为我不允许更改getHtmlAttributes()的声明
-声明,第二次调用函数是返回strtok位置的原因,这是练习(我猜)所暗示的。感谢您的时间!我最终使用start=(ptr stringT)+strlen(ptr)+1;返回start;
int getHtmlAttributes(const char *string, int start, char *attrName, char *attrValue)
{
char *buf;
char *attrptr;
char *ptr;
// copy the substring starting at start to buf
// you should add error checking (buf may become NULL)
buf = strdup( string+start );
// first step: tokenize on whitespace; we stop at the first token that contains a "="
for( attrptr = strtok( buf, " \t" ); attrptr && (ptr = strchr( attrptr, '=' )) != NULL; attrptr = strtok( NULL, " \t" ) ) ;
if( attrptr ) {
// copy everything before "=" to attrName
sprintf( attrName, "%.*s", ptr-attrptr, attrptr );
// copy everything after "=" to attrValue
strcpy( attrValue, ptr+1 );
// the next start is the current start + the offset of the attr found
// + the length of the complete attr
start += (attrptr - buf) + strlen( attrptr );
free( buf );
return start;
} else {
// no more attribute
free( buf );
return -1;
}
}