【问题标题】:strtok not working as expected, works only for first few iterationsstrtok 未按预期工作,仅适用于前几次迭代
【发布时间】:2015-07-12 04:02:11
【问题描述】:

我正在使用 strtok 拆分字符串,它在前 4 次迭代中按预期工作,但之后开始混乱。该程序应该采用诸如“david 1 2 3 4 5”之类的行并打印出名称加上数字“david 15”的总和......但是我遇到了strtok的问题。

编辑:我将数字作为以后使用代码的指针(这只是一个 sn-p)

这是我的 C 脚本:

#include <stdio.h>
#include <string.h>

char str1[50];
char *token;
char *end;
long int *number;
int loop = 1;
while(loop){
    fgets(str1,50,stdin);
    token = strtok(str1," ");
    printf("%s ",token);
    *number = 0;
    while(token != NULL){
        token = strtok(NULL," ");
        if(token != NULL){
            *number = *number + strtol(token,&end,0);
        }
    }
    printf("%li\n",*number);
}

有了这个输入:

David 10 10 10 10 10

我得到这个输出:

David 40

预期的输出是:

David 50

怀疑strtok,我把这些测试打印语句:

char str1[50];
char *token;
char *end;
long int *number;
int loop = 1;
while(loop){
    fgets(str1,50,stdin);
    token = strtok(str1," ");
    printf("%s\n",token);
    *number = 0;
    while(token != NULL){
        printf("before new token: %s\n",token);    // <---HERE
        token = strtok(NULL," ");
        printf("after new token: %s\n\n",token);   // <---HERE
        if(token != NULL){
            *number = *number + strtol(token,&end,0);
        }
    }
    printf("%li\n",*number);
}  

并且具有相同的输入:

David 10 20 30 40 50

我明白了:

David
before new token: David
after new token: 10

before new token: 10
after new token: 20

before new token: 20
after new token: 30

before new token: 30
after new token: 4<

before new token: 4@
after new token: (null)

64

如您所见,它在最初的几次迭代中运行良好,但之后情况开始变差。如果有人知道发生了什么,我将不胜感激:)谢谢!

【问题讨论】:

  • 只是为了好玩,如果你在40后面加一个空格会怎样?
  • 40后已经有空格,输入为David 10 20 30 40 50
  • number 没有指向任何已定义的内容...
  • 在您的特定情况下,未初始化的 number 指针恰好指向 str[16],值 40 中的 0 字符。这意味着您在对值求和时修改输入字符串。添加 10、20 和 30 后,str[16] 设置为 60(小端序),即&lt; 的 ASCII 码。这就是您获得4&lt; 令牌的原因。这被解析为 4,加到 60,因此在下一次迭代中,旧令牌包含 @(ASCII 64)。

标签: c strtok string.h


【解决方案1】:

你得到 40 而不是 50 的原因是你丢弃了第一个令牌(即你通过 str1 时从 strtok 得到的那个,而不是 NULL)。进入循环前需要把它加到sum中,或者重新组织循环先add,然后调用strtoknext:

number = 0; // There is no point in making "number" a pointer
token = strtok(str1," ");
while(token != NULL){
    printf("%s ",token);
    number += strtol(token,&end,0);
    token = strtok(NULL," ");
}

Demo.

【讨论】:

  • 顺便说一句,我正在用 C 编程。 hmm 不行,我把 print 放在 while 循环中 strtok 行之前,做同样的事情
  • @Vaderico 非常适合我。请参阅我在答案底部添加的演示链接。
  • 啊,好吧,刚刚检查了一下,它工作得很好。太感谢了!赞成
【解决方案2】:

变量number 是一个指针(为什么?)但你永远不会让它指向任何地方,因此当你取消引用它时你会得到undefined behavior

简单的解决方案? 不要让它成为指针!

【讨论】:

  • 请参考我的编辑。我需要它作为以后使用的指针,这只是一个 sn-p。
  • @Vaderico 你仍然需要让它指向某个地方。此外,您很可能不需要它作为指针,因为您可以使用例如&amp;number 用非指针变量创建指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-26
相关资源
最近更新 更多