C-如何在没有string.h和动态内存分配的情况下串联字符串

时间:2019-01-13 16:39:00

标签: c string pointers malloc concat

我必须做运动,并给出以下结构:

typedef struct {
    char *str;
    unsigned int len;
} String;

我的任务是编写一个字符串连拍,将"Kartoffel""puffer"连成"Kartoffelpuffer"(马铃薯油条)。

String concat(String l, String r)

运行函数后,不应更改字符串lr。 首先,我在主目录中创建了两个字符串:

String1 *l = malloc(sizeof(String1));
String1 *r = malloc(sizeof(String1));
(*l).str = malloc(sizeof("Kartoffel"));
(*r).str = malloc(sizeof("puffer"));
(*l).str = "Kartoffel";
(*r).str = "puffer";
(*l).len = 9;
(*r).len = 6;

然后我编写了concat函数:

String1 concat(String1 l, String1 r) {
    unsigned int i = 0;
    String1 *newStr = malloc(sizeof(String1));
    /* +1 for '\0' at the end */
    newStr->str = malloc(l.len + r.len + 1);
    newStr->str = l.str;
    /* The following line is not working */
    newStr->str[l.len] = *r.str;
    newStr->len = l.len + r.len;
    return *newStr;
}

我试图做的是使用指针算术。 如果有一个指针指向一个像char *str这样的存储区的开头,那么应该可以用a[b]*((a) + (b))向右移动指针吗?当我运行代码时,我遇到了Segmentation Fault(我希望它是正确的翻译。原文:"Speicherzugriffsfehler")。 如果有人能给我一个提示,我将很感激。 PS:对不起,我的英语。

3 个答案:

答案 0 :(得分:2)

首先,(*l).str = "Kartoffel";使(*l).str指向"Kartoffel"字符串文字,这意味着分配给(*l).str的{​​{1}}的原始内存丢失了。与malloc()相同。为避免这种情况,您可以采取的措施之一是通过循环for循环中的字符将字符串复制到分配的缓冲区中(因为您不能使用(*r).str = "puffer";)。

然后,在string.h函数中,您执行相同的操作。您用concat()newStr->str分配了内存(正确地为空终止符分配了额外的malloc()),但是在下一行中,您将该指针重新分配为指向{{1 }},它仍然指向字符串文字。然后,使用char尝试修改字符串文字,在C中这是未定义的行为。

解决此问题的方法可以再次是将两个字符串复制到l.str分配的缓冲区中。

答案 1 :(得分:1)

将内存分配给newStrnewStr->str
可以使用两个指针。 char *to, *from;
to = newStr->str;from = l.str;设置指针
*to = *from;复制字符
to++;from++;前进指针
重复直到*from == 0
from设置为from = r.str;
to不需要重置,因为它已正确放置在newStr->str的末尾。
重复字符的复制。
重复前进指针。
*to = 0;

设置终止0

答案 2 :(得分:1)

非常感谢您的帮助! 正如你们所说,我写了另一种方法来复制字符串。

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{
    ifstream myfile ("Mohamad.txt", ios::in);
    if(myfile.is_open())
    {
    cout<<"the file has been read!."<<endl;
    int id ;
    string name;
    double money;
    while(myfile>>id>>name>>money)
    {
       cout<< id << "  "<<name<<"  "<<money<<endl;
    }
    }
    else
    {
        cout<<"failed"<<endl;
    }
    return 0;
}

我这样编辑了concat:

char * copyStr (char * dest,char * src){
    unsigned int index;
    for (index = 0; src[index] != '\0'; index++) {
            dest[index] = src[index];
    }
    dest[index] = '\0';
    return dest;
}

使用String1 concat (String1 l, String1 r){ String1 *newStr = malloc(sizeof(String1)); newStr->str = malloc(l.len+r.len+1); copyStr(newStr->str,l.str); copyStr((newStr->str+l.len),r.str); newStr->len = l.len+r.len; return *newStr; } 将移动指针。如果l.len为9,则指针将指向第10个字节,即第一个字符串l的结尾。因此,字符串r将被复制到第一个字符串l后面的存储器中。