【问题标题】:A function that returns nth character from a string从字符串中返回第 n 个字符的函数
【发布时间】:2021-12-17 03:55:55
【问题描述】:

我正在尝试从字符串中获取第 n 个字符。但是,它从第 n 个字符开始返回字符串。

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

char *test(char input[],int position){

    char *result= malloc(sizeof(char)*100);
    result=&input[position];
    return result;
}

int main(){
    char *k;
    k=test("abcdefghi\n",3);
    printf("%s",k);
}

上面的代码返回 defghi 而不仅仅是 d。 我不确定这里出了什么问题。

【问题讨论】:

  • 如果你的函数应该返回一个字符(char),为什么要让它返回char *(指向char的指针)?同理,如果你想打印一个字符,为什么要使用%s(打印一个字符串),而不是%c(打印一个字符)?
  • 另外,我怀疑你根本不需要使用malloc
  • 您正在泄漏内存,因为您覆盖了从 malloc() 返回的 result 值。
  • 如果你真的想接收字符作为给定字符串的偏移量(input + position 会更简单,顺便说一下)你可以通过printf("%c", *k); 打印这个单个字符——注意你需要取消引用指针...
  • 嗨。请阅读How to Ask 并使用tour

标签: c char printf c-strings function-definition


【解决方案1】:

您混淆了字符串和字符。你可能想要这个:

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

char test(char input[], int position){
   return input[position];
}

int main(){
    char k = test("abcdefghi\n",3);
    printf("%c", k);
}

这将打印出来

d

这很简单,您实际上不需要函数。通常你有一个指向字符串或字符数组的指针,你可以像这样选择第 n 个字符:

char sometext[] = "abcdefghi\n";
...
char k = sometext[3];

【讨论】:

    【解决方案2】:

    您可能应该只返回一个 char,如其他答案所示。

    但如果你真的需要返回char *,你应该这样做。

    您只需要分配 2 个字符 - 一个用于您要返回的字符,一个用于尾随空字节。

    您需要将字符复制到分配的内存中,而不是重新分配指针变量。

    char *test(char input[],int position){
        char *result= malloc(2);
        result[0] = input[position];
        result[1] = '\0';
        return result;
    }
    

    调用者应该在打印后释放内存。

    int main(){
        char *k;
        k=test("abcdefghi\n",3);
        printf("%s\n",k);
        free(k);
    }
    

    【讨论】:

    • 虽然技术上是正确的,但我认为返回嵌入在字符串中的单个字符并不是一个好主意,内存分配速度不必要地慢并且容易出错(在某个时间点有人会 忘记释放...)。
    • 已经有另一个答案显示如何使用char 进行操作。我认为当他们尝试使用char * 进行操作时,这对显示他们做错了什么很有启发性。
    • 接受论点 - 并建议在答案中添加此解决方案存在问题的原因(请参阅我的评论),并可能链接到其他答案...
    • 我已经更新了答案以指定上下文。
    【解决方案3】:

    如果要从第 n 个位置复制字符串:

    char *copyFronNthPosiztion(const char *input, size_t position)
    {
        size_t len = strlen(input);
        char *result = NULL;
        if(position < len)
        {
            result = malloc(len - position + 1);
            strcpy(result, input + position);
        }
        return result;
    }
    

    如果你想拥有第 n 个字符,你确实需要任何函数。只需使用第 n 个索引。

    如果你想有一个单一的字符字符串:

    #define NTH(str, pos)   ((char[]){(str)[pos], 0})
    
        k=NTH("abcdefghi\n",3);
        printf("%s",k);
    

    【讨论】:

    • 你应该解释((char[]){(str)[pos], 0}),这可能超出了OP的范围。
    【解决方案4】:

    我正在尝试从字符串中获取第 n 个字符。然而,它 从第 n 个字符开始返回字符串。

    功能

    char *test(char input[],int position){
    

    不返回字符。它返回一个指针。

    此外,该函数存在内存泄漏,因为首先分配了内存并将其地址分配给指针result,然后重新分配指针

    char *result= malloc(sizeof(char)*100);
    result=&input[position];
    

    这样分配内存的地址就丢失了。

    除此之外,参数position 的值可以超过所传递字符串的长度。所以函数可以调用未定义的行为。

    如果函数返回一个指向字符的指针,那么输出指向的字符需要 1) 取消引用指针和 2) 在调用 printf 时使用转换说明符 %c 而不是 %s

    由于传递的字符串在函数内没有被改变,所以相应的参数应该用限定符const声明。

    函数可以通过以下方式声明和定义

    #include <string.h>
    #include <stdio.h>
    
    char * test( const char input[], size_t position )
    {
        char *result = NULL;
    
        if ( position <= strlen( input ) )
        {
            result = ( char * )( input + position );
        }
    
        return result;
    }
    

    你应该在 main 中写

    char *k;
    
    k = test( "abcdefghi\n", 3 );
    
    if ( k != NULL ) printf( "%c\n", *k );
    

    【讨论】:

    • 我个人觉得在返回的指针上也保留 constness 会更好,请考虑上一个示例中的 *k = 0;(因此以安全性为代价)。
    • 在一个完美的世界里,我实际上会overload - 承认,可能超出了 QA 的范围......
    • @Aconcagua 这不是 C++。没有函数重载的是C。因此,所有 C 标准字符串函数都遵循一般约定,即它们返回指向常量字符串的非常量指针。例如看函数 strchr char *strchr(const char *s, int c); 的声明
    • 你没有点击我的链接,是吗?它们确实从 C11 开始存在,至少 有点(是的,非常不方便)。是的,我知道标准中存在该模式 - 并且从未达成一致,因此也不会在自定义函数中遵循它,更高的安全性(我认为该模式只是出于兼容性原因而存在,而不是破坏现有的代码'不处理 constness - 但这与自定义函数的开发和调用无关,const 关键字存在已久...)。
    • @Aconcagua 对于初学者这么简单的问题来说太复杂了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    • 2013-04-14
    • 2012-02-26
    相关资源
    最近更新 更多