为了账号安全,请及时绑定邮箱和手机立即绑定

如何以标准的方式修剪前导/尾随空格?

如何以标准的方式修剪前导/尾随空格?

C
心有法竹 2019-06-18 10:56:31
如何以标准的方式修剪前导/尾随空格?是否有一种干净的、最好是标准的方法来从C中的字符串中修整前导和尾随空格?我会自己动手,但我会认为这是一个同样通用的解决方案的共同问题。
查看完整描述

3 回答

?
qq_花开花谢_0

TA贡献1835条经验 获得超6个赞

如果可以修改字符串:

// Note: This function returns a pointer to a substring of the original string.
// If the given string was allocated dynamically, the caller must not overwrite
// that pointer with the returned value, since the original pointer must be
// deallocated using the same allocator with which it was allocated.  The return
// value must NOT be deallocated using free() etc.char *trimwhitespace(char *str){
  char *end;

  // Trim leading space
  while(isspace((unsigned char)*str)) str++;

  if(*str == 0)  // All spaces?
    return str;

  // Trim trailing space
  end = str + strlen(str) - 1;
  while(end > str && isspace((unsigned char)*end)) end--;

  // Write new null terminator character
  end[1] = '\0';

  return str;}

如果不能修改字符串,则可以使用基本相同的方法:

// Stores the trimmed input string into the given output buffer, which must be// large enough to store the result.  
If it is too small, the output is// truncated.size_t trimwhitespace(char *out, size_t len, const char *str){
  if(len == 0)
    return 0;

  const char *end;
  size_t out_size;

  // Trim leading space
  while(isspace((unsigned char)*str)) str++;

  if(*str == 0)  // All spaces?
  {
    *out = 0;
    return 1;
  }

  // Trim trailing space
  end = str + strlen(str) - 1;
  while(end > str && isspace((unsigned char)*end)) end--;
  end++;

  // Set output size to minimum of trimmed string length and buffer size minus 1
  out_size = (end - str) < len-1 ? (end - str) : len-1;

  // Copy trimmed string and add null terminator
  memcpy(out, str, out_size);
  out[out_size] = 0;

  return out_size;}


查看完整回答
反对 回复 2019-06-18
?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

这里有一个将字符串转换到缓冲区的第一个位置的方法。您可能需要这种行为,以便如果动态分配字符串,仍然可以在TRIM()返回的指针上释放它:

char *trim(char *str){
    size_t len = 0;
    char *frontp = str;
    char *endp = NULL;

    if( str == NULL ) { return NULL; }
    if( str[0] == '\0' ) { return str; }

    len = strlen(str);
    endp = str + len;

    /* Move the front and back pointers to address the first non-whitespace
     * characters from each end.
     */
    while( isspace((unsigned char) *frontp) ) { ++frontp; }
    if( endp != frontp )
    {
        while( isspace((unsigned char) *(--endp)) && endp != frontp ) {}
    }

    if( str + len - 1 != endp )
            *(endp + 1) = '\0';
    else if( frontp != str &&  endp == frontp )
            *str = '\0';

    /* Shift the string so that it starts at str so that if it's dynamically
     * allocated, we can still free it on the returned pointer.  Note the reuse
     * of endp to mean the front of the string buffer now.
     */
    endp = str;
    if( frontp != str )
    {
            while( *frontp ) { *endp++ = *frontp++; }
            *endp = '\0';
    }


    return str;}

检验正确性:

int main(int argc, char *argv[]){
    char *sample_strings[] =
    {
            "nothing to trim",
            "    trim the front",
            "trim the back     ",
            " trim one char front and back ",
            " trim one char front",
            "trim one char back ",
            "                   ",
            " ",
            "a",
            "",
            NULL    };
    char test_buffer[64];
    int index;

    for( index = 0; sample_strings[index] != NULL; ++index )
    {
            strcpy( test_buffer, sample_strings[index] );
            printf("[%s] -> [%s]\n", sample_strings[index],
                                     trim(test_buffer));
    }

    /* The test prints the following:
    [nothing to trim] -> [nothing to trim]
    [    trim the front] -> [trim the front]
    [trim the back     ] -> [trim the back]
    [ trim one char front and back ] -> [trim one char front and back]
    [ trim one char front] -> [trim one char front]
    [trim one char back ] -> [trim one char back]
    [                   ] -> []
    [ ] -> []
    [a] -> [a]
    [] -> []
    */

    return 0;}

源文件是trim.c。用“cc trim.c-o TRIM”编译。


查看完整回答
反对 回复 2019-06-18
?
慕码人8056858

TA贡献1803条经验 获得超6个赞

我的解决方案。字符串必须是可变的。相对于其他一些解决方案的优点,它将非空格部分移至开头,这样您就可以继续使用旧指针,以防您以后不得不释放()它。

void trim(char * s) {
    char * p = s;
    int l = strlen(p);

    while(isspace(p[l - 1])) p[--l] = 0;
    while(* p && isspace(* p)) ++p, --l;

    memmove(s, p, l + 1);}

此版本创建字符串的副本,而不是在适当的位置进行编辑。strn心得()需要_GNU_source,所以您可能需要使用malloc()和strncpy()创建您自己的strn达普()。

char * trim(char * s) {
    int l = strlen(s);

    while(isspace(s[l - 1])) --l;
    while(* s && isspace(* s)) ++s, --l;

    return strndup(s, l);}


查看完整回答
反对 回复 2019-06-18
  • 3 回答
  • 0 关注
  • 434 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信