【问题标题】:Moving a string from one array to another in C [closed]在C中将字符串从一个数组移动到另一个数组[关闭]
【发布时间】:2023-03-25 14:40:01
【问题描述】:

我想获取一个包含字母和字符的字符串,然后只过滤掉字母。然后我想重用该字符串并将其放入数组中。我将如何在 C 中做到这一点?
我使用了isalpha(),但只使用了printf,而不是变量。 感谢您的帮助。

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

int main(void)
{
    int i;
    string w = "name1234";
    string new ="";
    int length = strlen(w);

    for (i=0; length > i; i++)
    {
        if (isalpha(w[i]))
        {
            new = w;
        }
    }
    printf("This is the new one: %s\n", new);  //it should be 'name' not 'name1234'
    return 0;
}

【问题讨论】:

    标签: c arrays string filter


    【解决方案1】:
    #include <stdio.h> 
    #include <string.h>  
    #include <ctype.h>
    
    int main(void)
    {
        int i, newx;
        char w[] = "name1234";
    
        int length = strlen(w);
    
        // in C99 or greater, you can do
        // char new[length+1];
        // to get a variable-length local array, instead of using malloc
        char* new = malloc(length+1);
        if (!new)
        {
             fprintf(stderr, "out of memory\n");
             return 1;
        }
    
        for (i = 0, newx = 0; length > i; i++)
        {
            if (isalpha((unsigned char)w[i]))
            {
                new[newx++] = w[i];
            }
        }
        new[newx] = '\0';
    
        printf("This is the new one: %s\n", new);  //it should be 'name' not 'name1234'
        free(new); // this isn't necessary since all memory is freed when the program exits
                   // (and it isn't appropriate if new is a local array) 
        return 0;
    }
    

    【讨论】:

    • 别忘了释放内存 :)
    • +1 用于错误检查 malloc 的结果,但 -1 用于最后不释放指针。
    • 另外,strlen 返回一个 size_t,而不是一个 int。
    • 在退出 main 之前不释放内存的反对票?这太荒谬了。无论如何,我为实际上不知道该语言的书呆子添加了freesize_t 可以转换为 int,如果你知道它足够大,可以容纳字符串的大小,就没有理由不使用 int
    • 顺便说一句,亚历克斯,如果你要为length 要求size_t,你也应该为inewx 要求它......但这是荒谬和毫无意义的迂腐。
    【解决方案2】:

    这是一个简单的代码。确保你理解每一行。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main()
    {
        char org[]="abc123defg";
        int size=sizeof(org)/sizeof(org[0]);   //size will hold the original array length 
        char* res=malloc((sizeof(char)*size)+1);  //+1 for the '\0' char that indicates end of a string
        if(!res)
            return 1; //allocation failed
        int i; int k=0;
        for(i=0;i<size;i++)
        {
            if(isalpha(org[i])) {
                res[k]=org[i];
                k++;
            }
        }
        res[k]='\0';
        printf("%s\n", res);  //now it will be abcdefg
        free(res);  //free the memory I've allocated for the result array
        return 0;
    }
    

    【讨论】:

    • sizeof 函数返回 size_t,而不是 int。此外,在 C 中,sizeof(char) 始终为 1,因此包含它是多余的。最后,您没有在指针生命周期结束时释放指针。
    • 隐式转换使其成为有效的int,只有size_t值太长才会溢出,sizeof(org)/sizeof(org[0])永远不会溢出。
    • 那也是错的,sizeof(org)是11*sizeof(char),因为org是一个数组。他没有把这个数组传给函数,所以数组不会在指针中衰减它的大小仍然是 11*sizeof(char)。用户是正确的,我也无缘无故地看到了很多其他的反对票(也在我的问题上)。
    • @RamyAlZuhouri 你误会我了。在实际应用程序中,org 可能是 char*,而不是数组。如果 OP 没有意识到 sizeof/sizeof only 适用于数组,而不是指针,它将导致一个错误......我们每隔几天就会在 SO 看到一个错误。
    • @RamyAlZuhouri 我的意思是一个处理未知长度字符串的应用程序。我的意思是一个应用程序,其中字符串作为参数传入,而不是在main 中预定义为测试用例,如此处。至于静态数组,除非您使用 VLA,否则它们会施加任意长度限制。
    【解决方案3】:

    定义正确的数据类型 char * 而不是字符串。您想过滤字符串 A 并将结果放入 B,您必须:

    1) Create char *a[size], char *b[size];
    2) iterate over the "string" A and verify if the actual position (char) meets the requirements to go to the "string" B;
    3) if it does, just do b[pos_b] = a[i]; and increment the variable pos_b.
    

    您必须声明 pos_b,因为您在数组 b 中的位置可能与您在数组 A 中的位置不同。因为,您只是在数组 b 中添加字母。

    【讨论】:

      【解决方案4】:

      这是学术版:

      const char* w= "name1234";
      char* filteredString= (char*)malloc(sizeof(char));
      const long length=strlen(w);
      long size=0;
      for(long i=0; i<length; i++)
      {
          if(isalpha(w[i]))
          {
              size++;
              filteredString=(char*)realloc(filteredString, (size+1)*sizeof(char));
              filteredString[size-1]=w[i];
          }
      }
      filteredString[size]=0;
      puts(filteredString);
      

      只是为了学习使用 realloc,但你可以在堆栈上分配整个字符串并搞砸内存使用,realloc 占用 CPU。

      【讨论】:

        【解决方案5】:

        好吧,我对您的代码进行了一些小修改以使其正常工作,但您可以使用一些库,例如 string.h。希望你能理解:

        #include <stdlib.h>
        #include <stdio.h>
        #include <string.h>
        #include <ctype.h>
        
        int main(void)
        {
            int i, j = 0;
            /* I limited your strings to avoid some problems. */
            char w[20]  = "name1234";
            /* The name "new" is a reserved word in C (at least in my IDE). */
            char nw[20] = "";
            int length  = strlen(w);
            for(i = 0; i < length; i++)
            {
                /* I added the special string end character '\0'. */
                if(isalpha(w[ i ]) || w[ i ] == '\0')
                {
                    nw[ j ] = w[ i ];
                    j++;
                }
            }
            printf("This is the new one: %s\n", nw);
            return 0;
        }
        

        【讨论】:

        • strlen 函数返回 size_t,而不是 int。
        • @AlexReynolds 你是因为size_t 而否决了这个答案的人?如果是这样,并且只有如果,环顾四周,你会看到一群人在使用strlen() 时使用int 而不是size_t,即使是认真的开发人员也使用int,恕我直言毫无意义,超过 32^2-1 个字符的字符串是不太可能的,一个安全的系统不应该让用户 malloc(4GB) 就这样。
        • @Kira 确实。这些不赞成投票是不必要的,也不能反映编程能力。正如我在回答中指出的那样,为length 调用size_t 而为索引ij 调用not 是错误且无能的,表明不了解类型一致性。
        • @JimBalter 如果我这样做(int) strlen( ) 是否被认为是正确的?
        • @AlbertoBonsanto 这已经是正确的,只要字符串长度不超过int 的容量。添加演员表是不必要的,演员表可以隐藏真正的错误。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-11
        • 2016-08-16
        • 1970-01-01
        • 1970-01-01
        • 2018-02-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多