【问题标题】:Program crashes with strtok [C]程序使用 strtok [C] 崩溃
【发布时间】:2018-04-26 14:42:54
【问题描述】:

我在使用函数strtok() 时遇到了一些问题。 在这个练习中,我的老师要求使用它来标记单个字符串,然后将偶数单词保存在列表中,然后打印所有偶数标记及其出现。但是在我写入输入字符串后程序崩溃了。谁能解释一下问题出在哪里?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define Dim 100

struct node{
int occ;
char sbuffer[Dim];
struct node *next;
}; 

struct node *first = NULL;

void occorrenze();
void insert(char *tkn);

int main(){

char array[Dim];
char buff[Dim];
char* token;

printf("Insert string: ");
gets(array);

for(token=strtok(array, " ") ; token!=NULL ; token=strtok(NULL," ") ){

    if ((strlen(token)%2)==0){
        insert(token);
        }

}

occorrenze();

 }

 void insert(char *tkn) {
 struct node *new_node;
 new_node = (struct node*)malloc(sizeof(struct node));
 strcpy(new_node->sbuffer, tkn);
 new_node->occ = 1;
 new_node->next = first;
 first = new_node;
 }

 void occorrenze() {
 struct node *p;
 struct node *s;
 for(p = first; p != NULL; p = p->next){    
     for(s = p; s != NULL; s = s->next){
         if(strcmp(s->sbuffer, p->sbuffer) == 0){
         p->occ++;
         }
      }
 }
 printf("\n%s\n%d\n",p->sbuffer, p->occ);
 }

(对不起我的英语不好^^)

【问题讨论】:

  • 程序在哪里崩溃了?如果您在调试器中运行它,它应该会告诉您这条非常重要的信息,您可以将其添加到您的问题中
  • 它在第一个 for 之前在函数 occorrenze() 中崩溃
  • 调试器会告诉你代码崩溃的确切行,而不是像你刚刚给我们的那样模糊的东西。

标签: c list token strtok


【解决方案1】:

问题是你在occorrenze()末尾的printf()

printf("\n%s\n%d\n",p->sbuffer, p->occ);

此时 p 为 NULL,因为您的 for 循环已完成

for (p = first; p != NULL; p = p->next) {

您用于查找匹配项的代码基本上是正确的,我只需对其稍作修改(您只需要一个循环)并将其移至insert(),这样您就不必添加单词 a第二次如果它已经在列表中,那么occorenze() 可以简单地遍历列表并打印单词及其occ 值:

void insert(char *tkn) {
    struct node *new_node;
    new_node = (struct node*)malloc(sizeof(struct node));

    for (struct node *n = first; n != NULL; n = n->next) {
        if (strcmp(tkn, n->sbuffer) == 0) {
            n->occ++;
            return;
        }
    }

    strcpy(new_node->sbuffer, tkn);
    new_node->occ = 1;
    new_node->next = first;
    first = new_node;
}

void occorrenze() {
    for (struct node*n = first; n != NULL; n = n->next) {
        printf("%d %s\n", n->occ, n->sbuffer);
    }
}

【讨论】:

  • 你完全正确!我觉得真的很愚蠢..现在我必须更改其他内容才能每个偶数令牌只打印一次
  • 您的代码到底想做什么?目前,您似乎接受长度为 2 的字符串,然后计算每个 2 char 字符串重复了多少次?
  • 例如,如果输入是“偶数例子四偶数奇数”输出应该是“偶数2四1”
  • 啊,我现在明白了...您可能需要考虑检查insert() 中的重复单词,这样您的列表中的每个单词只有一次,occ 的值是正确的跨度>
  • 就是这样,我不知道如何检查重复(或更多)单词
猜你喜欢
  • 2014-04-05
  • 1970-01-01
  • 2012-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-28
相关资源
最近更新 更多