【问题标题】:Appending two strings without str functions在没有 str 函数的情况下附加两个字符串
【发布时间】:2015-09-06 20:44:10
【问题描述】:

我在试图弄清楚如何将 char 指针 c 附加到现有的 Struct String 时遇到问题。我希望能够接受这样的输入(考虑一个预定义的结构,其值为“Hello”)append(test,"world") 当我尝试使用strcatstrcpy 时出现错误,因为结构字符串是不是用于此函数的有效类型。

如何在不使用str 函数的情况下追加?

我目前有代码声明一个结构,并在这种情况下将 stuff 设置为结构内容的值 hello 我输入我的函数并检查该人传递的数据是否不是空值。我创建了一个名为 append 的新 String Struct 和 realloc memory 到前一个“stuff”的新大小加上 *c 的值。我应该使用 for 循环将点 [i] 处的 *c 内容获取到 append 的末尾吗?

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

typedef struct strstf {
    char  * stuff;
    size_t  length;
} String;

String * append(String * b, const char * c) {
    String * append;
    if (c != NULL) {
        /* creates memory the size of the original string buffer and the added string */
        b->stuff realloc(strlen(c) + strlen(b->stuff) + 1);
        strcpy(append, b->stuff);
        strcat(append, c);
        return append;  
    }
    if (append->stuff == NULL) {
        free(append);  
        return NULL;
    }
    return append;
}

【问题讨论】:

  • 您应该为append() 函数和append 变量选择不同的名称。
  • append = (String*) realloc(b-&gt;stuff,... --> 如b-&gt;stuff = realloc(b-&gt;stuff,...
  • 这一行:'if(!(c = NULL)){' 不正确,它将 NULL 分配给 c。所以“如果”永远是真的。这是始终将文字放在左侧的(许多)原​​因之一。 IE。 'if(!(NULL = c)){' 那么编译器会抛出一个错误信息,你就不需要花费宝贵的时间来调试这个问题了。
  • 这一行:'b->stuff realloc(strlen(c) + strlen(b->stuff) + 1);'不编译。它在“b->stuff”之后缺少一个“=”。在就运行时问题寻求帮助时,请发布干净编译的代码(包括所有需要的#include 语句、数据定义等)
  • 使用 realloc() 时,始终将返回值保存到临时变量中,然后检查 (!=NULL) 临时变量,然后再分配给实际的目标变量。否则,如果 realloc() 失败,它可以做到,那么 1) 原始指针丢失,导致内存泄漏 2) 对该目标变量(现在为 NULL)的任何取消引用都将导致 seg 错误事件

标签: c string struct append


【解决方案1】:

很多你的代码有问题。以下是我注意到的问题:

  1. 您在名为append 的函数中使用了变量名称append,这是错误的形式。我什至不确定这是否可以编译。
  2. = 运算符在实际需要 == 时使用。前者是为了 赋值,因此条件始终为真。
  3. realloc() 用于 b-&gt;stuff,这是一个 char*,但您将其转换为 String*。这在技术上可能可行,但它的形式确实很糟糕。
  4. b-&gt;stuff 上使用 realloc() 后,您仍然使用指针 b-&gt;stuff,即使 realloc() 使传递的指针无效并返回一个新指针。
  5. strcpystrcat 在指向类型 struct strstf 的指针上,当它们都需要 char*

以下代码有效。你只需要记住释放指针result result-&gt;stuff。这是一个很容易发生内存泄漏的地方。

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

typedef struct strstf {
    char   *stuff;   
    size_t  length;   
} String;

String *append(String *b, const char *c){
    String* result = malloc(sizeof(String)); /* allocate memory for the resulting string */

     if (c != NULL && b != NULL && b->stuff != NULL) { /* make sure nothing is NULL */
        result->length = strlen(c) + b->length; /* calculate the length of the new string */
        result->stuff = malloc(result->length + 1); /* allocate the memory for the char array (plus '\0' char) */
        strcpy(result->stuff, b->stuff); /* copy the first to the result */
        strcat(result->stuff, c); /* append the second to the first */
        return result;  /* return the result */
    }
    return NULL; /* something went wrong */
}

int main(int argc, char* argv[]) {
    String first;
    String* result;
    if (argc != 3) {
        printf("The syntax of the command was incorrect.\n");
        return 1;
    }

    first.stuff = argv[1];
    first.length = strlen(argv[1]);

    result = append(&first, argv[2]);

    printf("Result: %s\n", result->stuff);

    free(result->stuff); /* DON'T FORGET THIS */
    free(result);

    return 0;
}

【讨论】:

  • 我喜欢这个解决方案,但是一点也不。当我在看起来很干净的 C 中点击 CamelCase String 时,就像撞到了一堵砖墙。哎哟!真是太糟糕了。建议,改用strstf。您可以将它同时用于 struct_space 和 typedef 名称,或者,在这种情况下,您甚至根本不需要初始的 strstf。你可以简单地移动它来替换String。只是一个讨厌的东西,怪癖,随便你怎么称呼它,但是 C 中的大写是保留给系统使用的......(其他人显然会有不同的意见......)虽然:p 的答案很好
  • @DavidC.Rankin 如果这是我的程序,我肯定会使用另一个名称。但是,我使用了String这个名称,以遵循他原始代码的风格。这可能只是一个代码 sn-p,他可能必须进行一些不需要的重构才能更改它。
  • 很公平。当我撞到那堵墙时,我不得不插话。在宏伟的计划中,这并不重要,但对于老年人来说,我们有点卡在自己的方式中......您将来可能还想通过指出风格差异来帮助其他人。
  • 为了避免不必要的遍历 result-&gt;stuffstrcat(result-&gt;stuff, c);,请使用 strcpy(result-&gt;stuff + b-&gt;length, c);
猜你喜欢
  • 1970-01-01
  • 2013-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-20
相关资源
最近更新 更多