C 函数只返回字符串的字母

C 函数只返回字符串的字母,c,string,function,pointers,C,String,Function,Pointers,我写了一个程序,它应该获取一个字符串,然后返回一个字符串,其中只包含原始字符串中的字母,但它不起作用,也不知道为什么。有人能帮我吗 #include<stdio.h> char *only_letters(char *s1ptr, char *s2ptr) { while(*s1ptr) { if((*s1ptr >= 'a' && *s1ptr <= 'z') || (*s1ptr >= 'A' &&

我写了一个程序,它应该获取一个字符串,然后返回一个字符串,其中只包含原始字符串中的字母,但它不起作用,也不知道为什么。有人能帮我吗

#include<stdio.h>

char *only_letters(char *s1ptr, char *s2ptr)
{
    while(*s1ptr)
    {
        if((*s1ptr >= 'a' && *s1ptr <= 'z') || (*s1ptr >= 'A' && *s1ptr <= 'Z'))
        {
            *s2ptr = *s1ptr;
            s2ptr++;
        }
        s1ptr++;
    }
    *s2ptr = '\0';
    return s2ptr;
}

int main()
{
    char *s1ptr, *s2ptr;
    printf("\n Write a string:\n");
    scanf("%s", s1ptr);
    printf("\n%s\n", *only_letters(s1ptr, s2ptr));
    return 0;
}
#包括
字符*仅字母(字符*s1ptr,字符*s2ptr)
{
而(*s1ptr)
{

如果((*s1ptr>='a'&&&*s1ptr='a'&&&*s1ptr由于
s1ptr
未指向有效位置,因此
scanf
会失败,因此会遇到未定义的行为

尝试将变量声明为

char s1ptr[64], s2ptr[64]; //or whatever length suits you
另外,请注意

printf("\n%s\n", *only_letters(s1ptr, s2ptr));
将尝试取消引用
仅返回的字母(这是
字符*
,取消引用是
字符
),但您试图将其作为字符串读取(通过
%s
)。请删除取消引用运算符。

您有3个问题

  • s1ptr
    s2ptr
    是两个未分配的数组,它们将导致未定义的行为

  • 您正在将
    s2ptr
    增加到具有值
    \0
    的点。返回该值后,您将得到一个仅具有
    \0
    的字符串

  • 要显示字符串,必须在不带
    *
    的情况下传递它(不要取消引用)

  • 试试这个

    char *only_letters(char *s1ptr, char *s2ptr_)
    {
        char *s2ptr = s2ptr_;
        while(*s1ptr)
        {
            if((*s1ptr >= 'a' && *s1ptr <= 'z') || (*s1ptr >= 'A' && *s1ptr <= 'Z'))
            {
                *s2ptr = *s1ptr;
                s2ptr++;
            }
            s1ptr++;
        }
        *s2ptr = '\0';
    
        return s2ptr_;
    }
    
    int main()
    {
        char s1ptr[256]; // Long enough
        char s2ptr[256]; // Long enough
        printf("\n Write a string:\n");
        scanf("%s", s1ptr);
        printf("\n%s\n", only_letters(s1ptr, s2ptr));
    }
    
    char*only_字母(char*s1ptr,char*s2ptr_u)
    {
    char*s2ptr=s2ptr;
    而(*s1ptr)
    {
    
    如果((*s1ptr>='a'&&&*s1ptr='a'&&&*s1ptr除了使用无效指针之外,还使用了错误的格式说明符:

    printf("\n%s\n", *only_letters(s1ptr, s2ptr));
    
    由于
    仅\u字母
    返回
    字符*
    ,因此取消对其结果的引用将生成
    字符

    您的格式要求指向以零结尾的字符序列(“%s”)的指针,因此
    printf
    将把传递给它的
    char
    解释为指针。 在本例中,您返回的是指向最后一个
    '\0'
    字符的指针,而零恰好被解释为空指针,打印为“(null)”。
    在开始之前,需要保存结果指针的初始值

    可能是一个完整的、未经测试的修复程序:

    char *only_letters(char *s1ptr, char *s2ptr)
    {
        char* result = s2ptr;
        while(*s1ptr)
        {
            if((*s1ptr >= 'a' && *s1ptr <= 'z') || (*s1ptr >= 'A' && *s1ptr <= 'Z'))
            {
                *s2ptr = *s1ptr;
                s2ptr++;
            }
            s1ptr++;
        }
        *s2ptr = '\0';
        return result;
    }
    
    int main()
    {
        char s1ptr[1024], s2ptr[1024];
        printf("\n Write a string:\n");
        scanf("%s", s1ptr);
        printf("\n%s\n", only_letters(s1ptr, s2ptr));
        return 0;
    }
    
    char*only_字母(char*s1ptr,char*s2ptr)
    {
    char*result=s2ptr;
    而(*s1ptr)
    {
    
    如果(*s1ptr>=‘a & & s1ptr=’a’& & s1ptrp*>这是非常丑陋的C样式代码,很容易出错。虽然代码中的bug已经被早期的鸟类所修复,但这里是C++的方式:

    std::string only_letters (std::string input) {
        auto it = std::remove_if(input.begin(),input.end(),
            [](const char x) {return !std::isalpha(static_cast<unsigned char>(x));});
        input.erase(it,input.end());
        return input;
    }
    
    int main () {
        std::string input;
        std::cout << "Write a string:\n";
        std::cin >> input;
        std::cout << only_letters(input);
    }
    
    std::仅字符串\u字母(std::字符串输入){
    auto it=std::remove_if(input.begin(),input.end(),
    [](const char x){return!std::isalpha(static_cast(x));});
    input.erase(it,input.end());
    返回输入;
    }
    int main(){
    std::字符串输入;
    std::cout>输入;
    
    std::cout您的代码至少有三个缺陷。第一个缺陷在函数定义中

    char *only_letters(char *s1ptr, char *s2ptr)
    {
        while(*s1ptr)
        {
            if((*s1ptr >= 'a' && *s1ptr <= 'z') || (*s1ptr >= 'A' && *s1ptr <= 'Z'))
            {
                *s2ptr = *s1ptr;
                s2ptr++;
            }
            s1ptr++;
        }
        *s2ptr = '\0';
        return s2ptr;
    }
    
    有效的代码可以如下所示

    char * only_letters( const char *s1ptr, char *s2ptr )
    {
        char *p = s2ptr;
    
        while ( *s1ptr )
        {
            if ( ( *s1ptr >= 'a' && *s1ptr <= 'z' ) || ( *s1ptr >= 'A' && *s1ptr <= 'Z' ) )
            {
                *p++ = *s1ptr;
            }
            s1ptr++;
        }
    
        *p = '\0';
    
        return s2ptr;
    }
    
    第二个缺陷是您没有将内存分配给要写入数据的位置

    int main()
    {
        char *s1ptr, *s2ptr;
        //...
    
    Thr有效代码可以如下所示:

    int main()
    {
        const size_t N = 20;
        char s1ptr[N], s2ptr[N];
    
    fgets( s1ptr, N, stdin );
    
    考虑到这一点,而不是

    printf("\n%s\n", *only_letters(s1ptr, s2ptr));
    
    一定有

    printf("\n%s\n", only_letters(s1ptr, s2ptr));
    
    第三个缺陷是使用函数
    scanf
    读取字符串。该函数可以覆盖不属于数组的内存

    scanf("%s", s1ptr);
    
    最好使用函数
    fgets

    比如说

    int main()
    {
        const size_t N = 20;
        char s1ptr[N], s2ptr[N];
    
    fgets( s1ptr, N, stdin );
    
    最后,如果程序是用C编写的,那么main应定义为

    int main( void )
    

    如果意外:它是一个C++程序,那么你应该使用标准的C++流代替C流和相应的C++函数而不是C函数。


    您还可以使用标准算法
    std::copy_if
    在目标字符串中只复制字母字符。

    我更改了它,但知道它总是打印
    (null)
    您期望得到什么?您正在返回一个指向ASCII 0的指针:
    *s2ptr='\0';return s2ptr;
    @User231454还有,为什么要取消对函数return的引用?它只打印一个字符。您是否试图从字符串中删除非字母字符?是的,它在开头说,正如前面所说的,“这是C代码,不是C++……”问题或示例中没有任何指向C++的。你需要C++解决方案吗?然后删除[C]标签。<代码> char * OnLyLyTeleStter();PrtTf(“\n%s\n”,*单字母(S1PTR,S2PTR)< /C>)意味着并非所有编译器警告都被启用为<代码>“%s”。“
    不属于
    char
    。请打开所有编译器警告。”。