我必须做运动,并给出以下结构:
typedef struct {
char *str;
unsigned int len;
} String;
我的任务是编写一个字符串连拍,将"Kartoffel"
和"puffer"
连成"Kartoffelpuffer"
(马铃薯油条)。
String concat(String l, String r)
运行函数后,不应更改字符串l
和r
。
首先,我在主目录中创建了两个字符串:
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:对不起,我的英语。
答案 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)
将内存分配给newStr
和newStr->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;
答案 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后面的存储器中。