【问题标题】:SOLVED-what am I doing wrong that strtok does right in splitting a string已解决-strtok 在拆分字符串时做错了什么
【发布时间】:2022-10-04 16:03:45
【问题描述】:

上一个问题是:strtok 在拆分字符串时做错了什么。也突然将 strtok 分离为一个函数不会产生正确的结果?

这是我第一次在 stackoverflow 中提出问题,如果这罗嗦且不连贯,请原谅我。问题的最后一部分在此问题正文的底部进行了详细说明。

所以,我正在做我的大学分配的课程评估,其中一个问题是:

删除重复的单词并只打印唯一的单词

输入:单个句子,其中每个单词用空格分隔

输出:用空格分隔的唯一单词[单词顺序应与输入相同]

例子:

输入: adc aftrr adc art

输出: adc aftrr art

现在,我有解决方案,即在空格上拆分字符串并将单词添加到数组(集合)中(如果它不存在),但它是实现部分让我把头发拔掉

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

#define MAX 20

int exists(char words[][MAX], int n, char *word){ // The existence check function
    for(int i=0;i < n;i++)
        if(strcmp(words[i],word) == 0) 
            return 1;
    return 0;
}

void removeDuplicateOld(char*);
void removeDuplicateNew(char*);

int main(){
    char sentence[MAX*50] = {0}; //arbitary length
    fgets(sentence,MAX*50,stdin);
    sentence[strcspn(sentence,"\n")]=0;
    
    printf("The Old One : \n");
    removeDuplicateOld(sentence);
    printf("\nThe New One : \n");
    removeDuplicateNew(sentence);
}

使用 strtok 分割字符串的函数:


void removeDuplicateNew(char *sentence){
    char words[10][MAX] = {0};
    int wi=0;
    char *token = strtok(sentence," ");
    
    while(token != NULL){
        if(exists(words,wi,token)==0) {
            strcpy(words[wi++],token);
        }
        token = strtok(NULL," ");
    }
    for(int i=0;i<wi;i++) printf("%s ",words[i]);
}

使用我的旧方法的旧函数(在我点击空格之前构造一个单词):


void removeDuplicateOld(char *sentence){
    char objects[10][MAX] = {0}; //10 words with MAX letters
    char tword[MAX];
    int oi=0, si=0, ti=0;
    
    while(sentence[si]!='\0'){
        if(sentence[si] != ' ' && sentence[si+1] != '\0')
            tword[ti++] = sentence[si];
        else{
            if(sentence[si+1] == '\0')
                tword[ti++]=sentence[si];
                
            tword[ti]='\0';
            
            if(exists(objects,oi,tword) == 0){
                strcpy(objects[oi++],tword);
            }
            ti=0; // The buffer[tword] is made to be overwritten

        }
        si++;
    }
    for(int i=0;i<oi;i++)
        printf("%s ",objects[i]);
}

已解决:将 if(sentence[si+1] == '\0') 改为 if(sentence[si+1] == '\0' && sentence[si]!=' ')


这是输出:

输入:abc def ghi abc jkl ghi

老一:

abc def ghi jkl

新的那一个 :

abc def ghi jkl

请注意,输入和输出中的尾随空格没有被检查,因为它们自己的驱动程序代码没有正确处理它们,而 strtok 方法可以,并且它通过了所有测试。


现在这两种方法似乎都产生了相同的结果,但它们确实根据测试用例产生了不同的输出,并且在将 strtok 方法作为一个单独的函数分离的顶部[removeDuplicateNew]失败在 main 方法中编写一个测试用例本身通过了所有测试,请参阅以下结果:

Old Method Test Case results

Strtok Method as Separate Function Test Case Results

以下已移至separate Question Thread

在 main 方法本身编码时:

int main(){
    char sentence[MAX*50] = {0}; //arbitary length
    fgets(sentence,MAX*50,stdin);
    sentence[strcspn(sentence,"\n")] = 0;
    
    char words[10][MAX] = {0};
    int wi=0;
    char *token = strtok(sentence," ");
    
    while(token != NULL){
        if(exists(words,wi,token)==0) {
            strcpy(words[wi++],token);
        }
        token = strtok(NULL," ");
    }
    for(int i=0;i<wi;i++) printf("%s ",words[i]);
}

Strtok Method as inline code Test Case Results

作为记录,它是刚刚放在 main 方法中的相同代码,所以当我将它作为函数分离并将字符串作为参数传递时,它突然无法正常工作。

也感谢任何关于我的问题构建的建议,措辞。

【问题讨论】:

  • 这似乎是学习如何debug 你的程序的好时机。例如,通过使用debugger 来逐句执行代码语句,同时监控变量及其值。
  • 您是否尝试过传递char**?意思是,指向包含单词的字符串(char*)的指针?
  • @Someprogrammerdude 我做了,但不幸的是,我所看到的只是代码将如何对它实际上可以产生正确结果的情况作出反应。我想不出任何边缘情况,因为我能想到的所有边缘情况都不会破坏程序,所以我无法真正分辨(或查看)差异。

标签: c string pointers split strtok


【解决方案1】:

你的代码...

void removeDuplicateOld(char *sentence){
    char objects[10][MAX] = {0}; //10 words with MAX letters
    char tword[MAX];
    int oi=0, si=0, ti=0;
    
    while(sentence[si]!='
猜你喜欢
  • 2014-01-21
  • 2021-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-16
  • 2018-08-02
相关资源
最近更新 更多