【问题标题】:How can I access the certain indexes of string using the function?如何使用该函数访问字符串的某些索引?
【发布时间】:2021-07-13 23:52:41
【问题描述】:

我正在练习并在互联网上找到了一些练习,它说我应该将str2复制到str1,也许主要问题是我应该只复制该字符串的某个索引(所以从str2[a]str2[b])。因此应输入AB,以便将复制索引的范围缩小到str1。所以在这里我使用了函数方法来解决这个问题,但是出了点问题。所以我不明白为什么函数不起作用,一定是我的理解有很大的错误,或者我做错了。

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

#define N 50

void myfunction(char str1[], char str2[], int a, int b);

int main() {
    char str1[N], str2[N];
    int a, b;
    printf("please input str1:");
    gets(str1);
    printf("please input str2:");
    gets(str2);
    printf("please input a and b:");
    scanf("%d%d", &a, &b);
    printf("str2=%s, str1=%s", str2, str1);
    myfunction(str1, str2, a, b);
    return 0;
}

void myfunction(char str1[], char str2[], int a, int b) {
    int i, j;
    for (i = a; i <= b; i++) {
        str1 += str2[i];
    }
}

【问题讨论】:

  • 您不能使用+= 追加到数组。
  • “出了点问题”……也就是说?
  • 从不永远使用getsdangerous 已从 C 语言中删除。使用例如fgets 代替。
  • mkrieger1,我的功能不起作用,所以我不知道哪里出错了。

标签: c substring c-strings function-definition


【解决方案1】:

如果要从字符数组中一个一个地复制字符,可以使用 for 循环,例如:-

认为 a 是 str1 的索引,b 是 str2 的索引,从哪里粘贴。

这不是确切的解决方案,但您可以从中获得帮助...

void myfunction(char str1[], char str2[],int a, int b)
{

    str1[a] = str2[b];

}

【讨论】:

  • 你没有循环。
  • 他们想将str2[a]str2[b]范围内的字符复制到str1
  • 我们可以覆盖,假设 str1 是 ['a', 'b', 'c'] 并且 str 2 是 ['d', 'e', 'f'] 那么我们可以这样做str1[1] = str2[1];这会将 str1 更改为 ['a', 'e', 'c']
  • Barmar,是的,这正是我需要的范围..
  • @Karan 如果a == 1b == 2,他们希望结果是str1 包含"ef"
【解决方案2】:

str1+= 不是分配给str1 元素的方式。它只是增加指针变量str1,这在这里没有用。

您可以使用两个变量,一个用于分配给str1 中的索引,另一个用于读取str2 中的索引。

您还需要检查是否到达str2 的末尾,并将空终止符添加到str1

void myfunction(char str1[], char str2[], int a, int b) {
    int i = 0, j = a;
    if (a >= 0 && a <= strlen(str2)) {
        for (; str2[j] && j <= b; i++, j++) {
            str1[i] = str2[j];
        }
    }
    str1[i] = '\0';
}

【讨论】:

  • 谢谢,添加了 a 的验证并修复了 i
  • 与其重复调用strlen()并导致O(len)时间,代码可以节省长度并且只调用一次strlen()
  • 它只调用一次strlen()。它在if,而不是for
  • 即使它在for 中,一个体面的编译器也会将其优化为一次调用。
  • 我不确定myfunction("abc", "123", 1, 1) 是否应该生成"2""2bc"。你选择了第一个,我选择了第二个,这似乎更符合 OP 的 main() 函数,它从用户那里读取 str1...
【解决方案3】:

不是在字符串之间复制字符,而是行:

str1 += str2[i];

只是增加指针。

你可能想要:

void myfunction(char str1[], char str2[], int a, int b) {
    int i, j = 0;
    for (i = a; i <= b; ++i) {
        str1[j] = str2[i];  // Copy the character in position i in str2 to position i in str1
        ++j;
    }
    str1[j] = '\0';
}

【讨论】:

    【解决方案4】:

    你的程序有多个问题:

    • 你不应该使用gets()
    • myfunction 只是增加 str1 而不是复制字符。
    • 您应该输出结果字符串。

    这里是修改版:

    #include <stdio.h>
    #include <string.h>
    
    #define N  50
    
    void myfunction(char str1[], char str2[], int a, int b);
    
    // safe replacement for gets()
    char *mygets(char *buf, size_t n) {
        int c;
        size_t i;
        while ((c = getchar()) != '\n') {
            if (c == EOF) {
                if (i == 0)
                    return NULL;
                break;
            }
            if (i + 1 < n)
                buf[i++] = c;
        }
        if (i < n) {
            buf[i] = '\0';
        }
        return buf;
    }
    
    int main() {
        char str1[N], str2[N];
        int a, b;
    
        printf("please input str1: ");
        if (!mygets(str1, sizeof str1))
            return 1;
        printf("please input str2: ");
        if (!mygets(str2, sizeof str2))
            return 1;
        printf("please input a and b: ");
        if (scanf("%d%d", &a, &b) != 2)
            return 1;
        printf("str2=%s, str1=%s\n", str2, str1);
        myfunction(str1, str2, a, b);
        printf("str1=%s\n", str1);
        return 0;
    }
    
    void myfunction(char str1[], char str2[], int a, int b) {
        int len1 = strlen(str1);
        int len2 = strlen(str2);
        int i, j;
        if (a < 0)
            a = 0;
        if (b > len2)
            b = len2;
        for (i = 0, j = a; j <= b; i++, j++) {
            str1[i] = str2[j];
        }
        if (i > len1) {
            /* do not truncate str1 but set the null terminator if needed */
            str1[i] = '\0';
        }
    }
    

    【讨论】:

    • 次要:为什么不总是空字符终止?也许放弃if (i &lt; n) {
    • @chux-ReinstateMonica 既然程序读取的是str1,想必他只想替换其中的一部分,而不是整个字符串。
    【解决方案5】:

    我应该将 str2 复制到 str1,也许主要问题是我应该 仅复制该字符串的某个索引(因此从 str2[a] 到 str2[b])。

    看起来您需要从另一个字符数组的初始位置开始复制一个字符串的一部分,因此字符数组还应保留由第一个字符串的字符构建的字符串。

    如果是这样,那么函数应该声明为

    char * myfunction( char str1[], const char str2[], size_t n );
    

    那是你原来函数的参数之一是多余的,因为使用指针算法你总是可以像这样调用函数

    myfunction( str1, str2 + a, b - a + 1 );
    

    在你的函数实现中似乎有错别字。

    void myfunction(char str1[], char str2[], int a, int b) {
        int i, j;
        for (i = a; i <= b; i++) {
            str1 += str2[i];
        }
    }
    

    例如变量j没有使用,并且在这个赋值语句中

    str1 += str2[i];
    

    左操作数是一个指针。所以你只是增加指针本身而不复制任何东西。例如如果str2[i] 包含字符'A' 那么上面的语句看起来像

    str1 += 'A';
    

    如果使用了 ASCII 字符表则语句等价于

    str1 += 65;
    

    即指针str1中存储的地址增加了65,将指向目标数组之外。

    同样在 main 中,在字符数组 str1 中输入一个字符串没有什么意义,因为它应该会在函数中被覆盖。

    注意函数gets是不安全的,不再被C标准支持。相反,您应该使用函数fgets

    这是一个演示程序,展示了如何在不使用标准字符串函数的情况下编写函数。

    #include <stdio.h>
    
    #define N 50
    
    char * myfunction( char str1[], const char str2[], size_t n )
    {
        char *p = str1;
        
        while ( *str2 && n-- )
        {
            *p++ = *str2++;
        }
        
        *p = '\0';
        
        return str1;
    }
    
    int main(void) 
    {
        char str1[N];
        char str2[N] = "Hello World!";
        
        puts( str2 );
        
        puts( myfunction( str1, str2 + 6, 6 ) );
        
        return 0;
    }
    

    程序输出是

    Hello World!
    World!
    

    如果你将通过以下方式更改功能

    char * myfunction( char str1[], const char str2[], size_t n )
    {
        char *p = str1;
        
        while ( *str2 && n )
        {
            *p++ = *str2++;
            --n;
        }
        
        while ( n-- ) *p++ = '\0';
        
        return str1;
    }
    

    那么它将与您应该熟悉的标题 &lt;string.h&gt; 中声明的标准字符串函数 strncpy 的行为方式相同。

    【讨论】:

    • 最后一个函数的行为确实像strncpy,同样容易出错且语义混乱。 OP 应该了解的一件事是:randomascii.wordpress.com/2013/04/03/stop-using-strncpy-already
    • @chqrlie 实际上任何 C 字符串函数都容易出错。您需要正确使用标准字符串函数。并且 strncpy 与其他字符串函数没有太大区别。
    猜你喜欢
    • 1970-01-01
    • 2021-06-01
    • 2019-10-09
    • 2020-05-13
    • 1970-01-01
    • 2019-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多