【问题标题】:Using Pointers and strtok()使用指针和 strtok()
【发布时间】:2014-01-01 11:41:59
【问题描述】:

我正在构建一个链接列表,需要您的帮助,因为我是 C 新手。 我需要输入一个如下所示的字符串:(word)_#_(year)_#_(DEFINITION(UPPER CASE))

例如:输入一个字符串 输入:invest_#_1945_#_TRADE

基本上,我希望构建一个函数来扫描 DEFINITION 并返回与之相关的单词。 输入要在字典中搜索的单词 输入:贸易 输出:在单词“invest”中找到“TREADE”

到目前为止,我设法使用 strtok() 函数,但现在我不确定如何打印第一个单词。

这是我能想到的:

  char split(char words[99],char *p)
 {

p=strtok(words, "_#_");
while (p!=NULL)
{
    printf("%s\n",p);
    p = strtok(NULL, "_#_");
}
return 0;

 }


 int main()
 {
char hello[99];
char *s = NULL;

printf("Enter a string you want to split\n");
scanf("%s", hello);
split(hello,s);
return 0;
 }

对我应该怎么做有什么想法吗?

【问题讨论】:

  • 抱歉编辑遇到问题
  • 删除不需要的数据,为什么没有引用的结构。
  • 看看strstr()
  • 好吧,对不起,我的结构我不小心包含在里面,我会把它拿出来。我拥有链接列表所需的所有函数,我正在寻找扫描我的字符串并有一个函数可以扫描我的 DEFINITION 并在我上面显示的示例中给出与它完全相关的单词
  • strtok() 查找字符串中的任何字符,如@wildplasser 所说,查看strstr()

标签: c string linked-list


【解决方案1】:

我认为您的问题是如何从格式化字符串中提取这三位信息。

函数strtok 并没有像你想象的那样工作:第二个参数不是一个文字分隔字符串,而是一个用作分隔符的字符集的字符串。

在你的情况下,sscanf 似乎是更好的选择:

#include <stdlib.h>
#include <stdio.h>

int main()
{
    const char *line = "invest_#_1945 _#_TRADE  ";

    char word[40];
    int year;
    char def[40];
    int n;

    n = sscanf(line, "%40[^_]_#_%d_#_%40s", word, &year, def);

    if (n == 3) {
        printf("word:   %s\n", word);
        printf("year:   %d\n", year);
        printf("def'n:  %s\n", def);
    } else {
        printf("Unrecognized line.\n");
    }

    return 0;
}

函数sscanf 根据给定的模式检查给定的字符串。粗略地说,该模式由以百分号开头的格式说明符、表示任意数量的空白字符(包括无)的空格和必须匹配 varbatim 的其他字符组成。格式说明符产生一个必须存储的结果。因此,对于每个说明符,必须在格式字符串之后给出一个结果变量。

在这种情况下,有几个块:

%40[^_] 将最多 40 个非下划线字符读入 char 数组。这是读取字符串的一种特殊情况。 sscanf 中的字符串实际上是单词,可能不包含空格。然而,下划线将是字符串的一部分,因此为了不占用第一个分隔符的下划线,您必须使用符号[^(chars)],这意味着:任何不包含给定字符的字符序列. (插入符号在这里进行否定,[(chars)] 表示给定字符的任何序列。)

_#_ 从字面上匹配第一个分隔符,即仅当接下来的字符是下划线哈希标记时,下划线。

%d 将十进制数读入整数。注意整数的地址必须在这里用&amp; 给出。

_#_ 匹配第二个分隔符。

%40s 将最多 40 个非空白字符的字符串读入 char 数组。

函数返回匹配结果的数量,如果该行有效,则应该是三个。函数sscanf 可能很麻烦,但可能是您在这里快速和肮脏输入的最佳选择。

【讨论】:

    【解决方案2】:
    #include <stdio.h>
    #include <string.h>
    
    char *strtokByWord_r(char *str, const char *word, char **store){
        char *p, *ret;
        if(str != NULL){
            *store = str;
        }
        if(*store == NULL) return NULL;
        p = strstr(ret=*store, word);
        if(p){
            *p='\0';
            *store = p + strlen(word);
        } else {
            *store = NULL;
        }
        return ret;
    }
    char *strtokByWord(char *str, const char *word){
        static char *store = NULL;
        return strtokByWord_r(str, word, &store);
    }
    
    int main(){
        char input[]="invest_#_1945_#_TRADE";
        char *array[3];
        char *p;
        int i, size = sizeof(array)/sizeof(char*);
        for(i=0, p=input;i<size;++i){
            if(NULL!=(p=strtokByWord(p, "_#_"))){
                array[i]=p;//strdup(p);
                p=NULL;
            } else {
                array[i]=NULL;
                break;
            }
        }
        for(i = 0;i<size;++i)
            printf("array[%d]=\"%s\"\n", i, array[i]);
    /* result
    array[0]="invest"
    array[1]="1945"
    array[2]="TRADE"
    */
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-16
      • 2015-07-17
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      相关资源
      最近更新 更多