C从字符串的前15个字符中获取完整的单词

时间:2015-07-12 01:55:05

标签: c string

我有一个函数将返回字符串的前13个字符或字符串的后13个字符:

char* get_headsign_text(char* string, int position) {
  if (position == 1){
    char* myString = malloc(13);
    strncpy(myString, string, 13);
    myString[13] = '\0'; //null terminate destination
    return myString;
    free(myString);
  } else {
    char* myString = malloc(13);
    string += 13;
    strncpy(myString, string, 13);
    myString[13] = '\0'; //null terminate destination
    return myString;
    free(myString);
  }
}

我想拥有它,以便函数只返回完整的单词(中间没有截断的单词)。

实施例: 如果字符串是"嗨我是克里斯托弗"

get_headsign_text(string, 1) = "Hi I'm "
get_headsign_text(string, 2) = "Christopher"

因此,如果函数会在一个单词中剪切,而是在最后一个单词之前剪切,如果是,如果它试图获得第二个单词,那么它将包括将被剪切的单词。

4 个答案:

答案 0 :(得分:1)

在考虑各种边缘情况时,代码的结构需要大幅改变。

例如:

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

inline int min_int(int a, int b) {
        return a < b ? a : b;
}

inline int is_word_char(char c) {
        return isgraph(c);
}

char* get_headsign_text(char* string, int position) {
        int start_index, end_index;
        if (position == 1) {
                start_index = 0;
        } else {
                start_index = 13;
        }
        end_index = min_int(strlen(string) + 1, start_index + 13);
        start_index = min_int(start_index, end_index);
        int was_word_char = 1;
        while(start_index > 0 && (was_word_char = is_word_char(string[start_index]))) {
                --start_index;
        }
        if(!was_word_char) {
                ++start_index;
        }
        while(end_index > start_index && is_word_char(string[end_index])) {
                --end_index;
        }
        int myStringLen = end_index - start_index;
        char *myString = malloc(myStringLen + 1);
        strncpy(myString, string + start_index, myStringLen);
        myString[myStringLen] = '\0';
        return myString;
}

int main(void) {
        char s[] = "Hi, I\'m Christopher";
        char *r1 = get_headsign_text(s, 1);
        char *r2 = get_headsign_text(s, 2);
        printf("<%s>\n<%s>\n", r1, r2);
        free(r1);
        free(r2);
        return 0;
}

也就是说,您发布的代码段存在许多其他问题/疑虑:

  • 在作业myString[13] = '\0';中,您正在分配尚未分配的内存。虽然您已经分配了13个字节,但myString[13]指的是超过最后一个分配字节的一个字节。
  • 执行return语句后没有任何内容,且永远不会调用free
  • 你不应该只是为了立即释放它而返回一块内存!向呼叫者提供一些东西只是为了把它带走是相当适得其反的。 :)
  • 您不验证字符串的大小。除非你绝对肯定只会在长度足够长的字符串上调用,否则当position2而你的字符串缓冲区只有10字节时,你的函数会出现段错误长。

答案 1 :(得分:0)

你需要检查你的最后一个字符是不是空格''然后它应该找到尾随空格并将你的字符串剪切到该索引。

答案 2 :(得分:0)

使用索引变量跟踪您的空间。如果字符数为13,并且当前字符不是空格或空终止符,则通过减去该字符数和最后一个空格索引来调整字符数。保存字符串,然后从最后一个空格索引继续。

答案 3 :(得分:0)

你有很多问题。

第一个问题,你在返回myString后自由了 - 这意味着这个函数不会释放字符串。

第二期。您分配了13个字符,然后将第13个字符设置为null。你确定这符合你的期望吗?

第三个问题 - 为什么要在字符串指针中添加13?该怎么办?

最后,您应该考虑使用哪个字符来分隔单词 - 当您想出哪个字符时,尝试扫描它并将字符串剪切到原来的位置。