Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.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/4/string/5.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如何将strtok中的位置指针设为int_C_String_Strtok - Fatal编程技术网

学习c如何将strtok中的位置指针设为int

学习c如何将strtok中的位置指针设为int,c,string,strtok,C,String,Strtok,这里的初学者, 对练习有点困惑: 页面上的最后一个(是德语)。我应该阅读HTML行并打印属性及其值。给出了应该使用的函数的声明。 有两件事让我恼火: 1.该行存储在一个const char字符串中,但我希望用户输入所需的HTML行。似乎不可能在运行时更改常量变量。如何在不更改给定声明的情况下实现此目标? 2.教程想让我把strtok搜索的位置作为一个整数返回,但我在网上读到这个值存储在strtok中,有没有办法转换它,或者以某种方式获得它 为了解决这个问题,我写了这段代码,但是程序在运行时崩溃了

这里的初学者, 对练习有点困惑: 页面上的最后一个(是德语)。我应该阅读HTML行并打印属性及其值。给出了应该使用的函数的声明。
有两件事让我恼火:
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;
         }
     }