【问题标题】:Delete space from string in ansi C从ansi C中的字符串中删除空格
【发布时间】:2012-05-23 10:07:11
【问题描述】:

我正在尝试在 ansi C 中的字符串中编写简单的函数修剪空间。

我的 str_utis.h:

#include <string.h>

const char* trim_str(char *input_str); 

我的 str_utils.c:

const char* trim_str(char* input_str){
    char* str = NULL;
    int len = strlen(input_str);
    int i = 0;
    for (i = 0; i < len - 1; i++){
        if (input_str[i] == ' ')
            ;
        else
            str += input_str[i];
    }
    return str;
}

当我尝试执行它时,我得到了段错误:

int main(int argc, char** argv) {
    const char* a = trim_str("Hey this is string");
    printf("%s", a);
    return 0;
}

为什么错了?怎么写正确?

谢谢。

【问题讨论】:

  • += 不是 C 中的字符串连接。它是指针添加。

标签: c string string.h


【解决方案1】:

您不能修改字符串文字。是UB。复制字符串并修改其内容。改变

char* str = NULL;
int len = strlen(input_str);

size_t len = strlen( input_str );
char *str = malloc( len + 1 );

然后继续复制非空白内容。

【讨论】:

  • 在这种情况下,“UB”代表什么?
  • UB,在 C 和 C++ 中,通常表示未定义的行为。 IOW,如果你正在做语言标准禁止你做的事情,你就会调用 UB——你不能说接下来会发生什么。
  • 出于某种原因,我在想“未初始化的缓冲区”,但这在这里没有意义:)
  • 是的,NULL 指针上的大多数操作都会导致 UB,(除了比较、赋值等)。所以,是的 input_str[ i ] 就像在 OP 的代码中一样,也会导致 UB。草案中有一个部分列出了这些未定义的行为——附件 L,第 2.3 节——应该可以帮助您入门。
【解决方案2】:

str 没有分配,你不能使用 += 附加到一个字符串。阅读 strncat。

【讨论】:

    【解决方案3】:

    通过这个。这将删除输入字符串两端的空格和制表符。

    const char* trim_str(char* input_str){
        char* str = NULL;
        int len = strlen(input_str);
        str = (char *)malloc(len+1);
        int i = 0;
        while(i < len && (input_str[i]==' ' || input_str[i]=='\t')){
            ++i;
        }
        int j = 0;
        while(i< len && input_str[i]!=' ' && input_str[i]!='\t'){
          str[j]= input_str[i];
          ++j;
          ++i;
        }
       str[j] = '\0';
    
       return str;
      }
    

    【讨论】:

      【解决方案4】:

      首先你需要得到不带空格的新字符串大小: 如果没有必要,你不想分配大字符串。

         const char* trim_str(char* input_str){
              char* str = NULL;
              int len = strlen(input_str);
              int i = 0;
              int newSize = 0; 
              for (i = 0; i < len - 1; i++){
                  if (input_str[i] == ' ')
                      ;
                  else
                      newSize++;
              }
              str = malloc( newSize+ 1 );
              str[newSize] = '\0'
      
              // put the code of the copy bytes here...
      
              return str;
          }
      

      【讨论】:

        【解决方案5】:
        char *trimdupstr(char *str)
        {
        size_t len, src,dst;
        char *new;
        
        if (!str) return NULL;
        len = strlen (str);
        new = malloc(len+1);
        if (!new) return NULL;
        
        for(src=dst=0; new[dst] = str[src++];   ) {
                if (new[dst] != ' ') dst++;
                }
        return new;
        }
        

        而且这个还删除了标签和 CR/LF:

        char *trimdupstr(char *str)
        {
        size_t len, src,dst;
        char *new;
        
        if (!str) return NULL;
        len = strlen (str);
        new = malloc(len+1);
        
        for (src=dst=0; str[src]; dst += len) {
                len = strspn(str+src, "\t \r\n" );
                src += len;
                len = strcspn(str+src, "\t \r\n" );
                memcpy (new+dst, str+src, len);
                src += len;
                }
        new[dst] = 0;
        return new;
        }
        

        【讨论】:

          【解决方案6】:

          这是一种相当安全的方法。

          void rtrim(char instrng[]) {
          assert (instrng != NULL);
          if (strlen(instrng) == 0) {
              return;
          }
          while (instrng[strlen(instrng)-1] == '\n' || instrng[strlen(instrng)-1] == ' ' ) {
              instrng[strlen(instrng)-1] = '\0';
          }
          return; 
          }
          

          【讨论】:

            猜你喜欢
            • 2010-12-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-11-20
            相关资源
            最近更新 更多