【问题标题】:Does this function I made correctly append a string to another string?我制作的这个函数是否正确地将一个字符串附加到另一个字符串?
【发布时间】:2017-09-11 07:59:21
【问题描述】:

我昨晚凌晨 3 点起床编码,今天醒来,在源文件中找到了这个:(诅咒词已编辑)

void append_this_stuff(char *stuff_to_append_to[], char **stuff_to_append, int position) {
  char the_actual_stuff[] = *(stuff_to_append_to);
  char *screw_me = *(stuff_to_append);

  int someNumber = strlen(screw_me);

  int j = 0;
  for (int i = position; i < (someNumber + position - 1); i++) {
    the_actual_stuff[i] = (screw_me + j);
    j++;
  } 

  stuff_to_append_to = &the_actual_stuff;
}

当我尝试编译它时,我得到了这个错误:

<project root>/src/brstring.c: In function ‘append_this_stuff’:
<project root>/src/brstring.c:38:28: error: invalid initializer
   char the_actual_stuff[] = *(stuff_to_append_to);
                            ^
<project root>/src/brstring.c:46:24: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
     the_actual_stuff[i] = (screw_me + j);
                        ^
<project root>/src/brstring.c:50:21: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
   stuff_to_append_to = &the_actual_stuff;

有人知道我这样做是否正确吗?我正在通过 C99 标准和 cmake 进行编译,并且我在 Fedora Linux 上使用 GCC,如果这会影响任何事情的话。

【问题讨论】:

  • 你为什么用c99? C11 出来很久了,得到了广泛的支持。

标签: c string char concatenation c99


【解决方案1】:

1.) 错误:无效的初始化程序:

char the_actual_stuff[] = *(stuff_to_append_to);

The_actual_stuff 是一个没有初始大小的数组。您的意思是使用指针指向内存地址吗?

2.) 警告:赋值从没有强制转换的指针生成整数:

the_actual_stuff[i] = (screw_me + j);

您正在尝试为没有初始大小的数组索引分配一个值。

附注:如果您打算将变量的值相加,您必须首先使用 * 取消引用指针。您正在向内存地址添加一个整数。

3.) 警告:来自不兼容指针类型的赋值

  stuff_to_append_to = &the_actual_stuff;

看到这个post:因为它很好地解释了它。

【讨论】:

    【解决方案2】:

    首先,char *stuff_to_append_to[] 是一个长度不确定的指针数组,这不是一个有效参数,因为数组的最后一维必须在传递给函数时指定,否则,通过指向类型的指针。

    接下来,char **stuff_to_append 是一个 指向 char 指针的指针,并且完全有效,但考虑到您在函数中使用了 stuff_to_append,很明显这不是您想要的。

    如果您希望在stuff_to_append 的末尾插入 stuff_to_append截断 stuff_to_append_to,只需将指向每个字符串的指针作为参数传递。虽然int position 很好,但选择 unsigned 值可能会更好,因为您不会在 negative 数组索引处插入。

    在您的函数内部,您必须验证stuff_to_append_to 中有足够的空间来保存从索引position 开始的stuff_to_append(包括nul-byte 的空间)

    考虑到这一点,您可能需要执行以下操作:

    void append_this_stuff (char *stuff_to_append_to, char *stuff_to_append, 
                            int position) 
    {
        int somenumber = strlen (stuff_to_append),
            lento = strlen (stuff_to_append_to),
            end = position + somenumber;
    
        if (end > lento) {
            fprintf (stderr, "error: insufficient space in stuff_to_append_to.\n");
            return;
        }
    
        for (int i = position; i < end + 1; i++)    /* +1 to force copy of nul-byte */
            stuff_to_append_to[i] = stuff_to_append[i - position];
    }
    

    你可以编写一个小测试程序来确认它的运行,例如

    #include <stdio.h>
    #include <string.h>
    ...
    int main (void) {
    
        char stuff[] = "my dog has fleas!",
            append[] = "cat has none!";
        int pos = 3;
    
        printf ("original: %s\n", stuff);
        append_this_stuff (stuff, append, pos);
        printf ("     new: %s\n", stuff);
    
        return 0;
    }
    

    使用/输出示例

    $ ./bin/append
    original: my dog has fleas!
         new: my cat has none!
    

    要使用指针算法而不是使用数组索引来做同样的事情,您可以重写append_this_stuff,类似于以下内容:

    void ats (char *to, char *from, int p)
    {
        if (p + strlen (from) > strlen (to)) {
            fprintf (stderr, "error: insufficient space in stuff_to_append_to.\n");
            return;
        }
    
        for (to += p; *from; to++, from++)
            *to = *from;
        *to = *from;
    }
    

    最后,如果这节课在你的思维过程中没有完全根深蒂固,“在面试你的第一个编程职位时,永远不要在招聘人员手中发布任何你不想要的东西。”使用不专业或可爱的变量名称,虽然它可能表达你的挫败感,但可能不会给人留下你想要的印象。说得够多了。

    【讨论】:

    • 看起来这行得通。我还将牢记这一课,并从我的代码中过滤掉所有的脏话。谢谢!
    • 当然,很乐意提供帮助,只是把它当作一个知道自己在说什么的顽固的老律师和工程师的一点建议......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-06
    • 2020-04-13
    • 2013-09-06
    • 1970-01-01
    • 2011-05-25
    相关资源
    最近更新 更多