我正在处理有关使用动态内存分配修改字符串的问题。我的代码的适用部分如下:
./dma 5
#include <stdio.h>
#include <stdlib.h>
char* strcopy(char* destination, char* source);
char *strconcat(char* destination, char* source);
int main(int argc, char *argv[]) {
int cmd, a=1, b, length_of_str, n, n2;
char* pstring[atoi(argv[1])];
for (b=0; b<atoi(argv[1]); b++) {
printf("Enter the length of string %d: ", b+1);
scanf("%d", &length_of_str);
pstring[b]=(char *)malloc(length_of_str*sizeof(char));
printf("Please enter string %d: ", b+1);
scanf("%s", &pstring[b]);
}
while (a!=0) {
printf("Your strings are: \n");
for (b=0; b<atoi(argv[1]); b++) {
printf("String number %d - \"%s\"\n", b+1, &pstring[b]);
}
printf("Options:\n");
printf("1 - Find string length\n");
printf("2 - Compare strings\n");
printf("3 - Copy strings\n");
printf("4 - Concatenate strings\n");
printf("5 - Quit\n");
printf("Please enter your option: ");
scanf("%d", &cmd);
switch (cmd) {
case 3:
printf("Enter the number of the source string: ");
scanf("%d", &n);
printf("Enter the number of the destination string: ");
scanf("%d", &n2);
strcopy(pstring[n-1], pstring[n2-1]);
break;
case 4:
printf("Enter the number of the source string: ");
scanf("%d", &n);
printf("Enter the number of the destination string: ");
scanf("%d", &n2);
strconcat(pstring[n-1], pstring[n2-1]);
break;
case 5:
a=0;
break;
default:
printf("Invalid Option.\n");
break;
}
}
free(pstring);
return 0;
}
char* strcopy(char* destination, char* source) {
destination=(char *)realloc(*source, sizeof(char)*strlength(destination));
for (; *source!='\0'; source++) {
*destination=*source;
destination++;
}
*destination='\0';
return destination;
}
char* strconcat(char* destination, char* source) {
destination=(char *)realloc(*source, sizeof(char)*strlength(destination));
for (; *destination!='\0'; destination++) {
}
for (; *source!='\0'; source++) {
*destination=*source;
destination++;
}
*destination='\0';
return destination;
}
我需要将realloc合并到我的串联和复制函数中(这很好,因为它们在另一个问题中起作用)。我尝试了多种方法,尝试了不同的语法,但似乎只出现了分段错误或无效的指针。我应该如何准确地合并realloc?预期的结果应如下所示:
Your strings are:
String number 1 – “first”
String number 2 – “second”
String number 3 – “third”
String number 4 – “fourth”
String number 5 – “fifth”
Options:
1 – Find string length
2 – Compare strings
3 – Copy strings
4 – Concatenate strings
5 – Quit
Please enter your option: 3
Enter the number of the source string: 2
Enter the number of the destination string: 5
Your strings are:
String number 1 – “first”
String number 2 – “second”
String number 3 – “third”
String number 4 – “fourth”
String number 5 – “second”
Options:
1 – Find string length
2 – Compare strings
3 – Copy strings
4 – Concatenate strings
5 – Quit
Please enter your option:
答案 0 :(得分:0)
一个主要问题是如何读取字符串:
scanf("%s", &pstring[b])
这里pstring[b]
的类型为char *
,由于malloc
的调用,它指向一些内存(除非malloc
失败,您忘记检查了)。
但是 &pstring[b]
是指向该指针的指针 ,类型为char **
。这几乎不是您想要的,并且会导致scanf
向本来不应该写入的地方写入内存,甚至可能超出分配的内存范围。当然,这导致了undefined behavior。
解决后,您需要记住,C语言中的char
字符串实际上称为 空终止 字节字符串 。 null-terminator 是所有标准字符串函数用来查找字符串结尾的内容。当然,这意味着x
个字符的字符串需要x + 1
的空格以适合终止符。因此,如果用户说他或她想要一个长度为6
的字符串(例如),然后输入foobar
作为输入,则需要 7
个字符的空间与终结者。您在其他地方(例如strcopy
函数)也遇到了终结者问题(或者缺少为它分配空间)。
您的scanf
调用也不会阻止用户输入比用户说的更长的字符串。如果用户说该字符串应为3
个字符,但随后输入foobar
,则会超出范围。不幸的是,仅凭scanf
就无法解决此问题,因为字段宽度修饰符必须是格式字符串的一部分。您可以使用scanf_s
函数来解决此问题,但C规范并未强制使用该函数,并且需要您定义一个特定的宏,以使其在实现中可用(例如,参见{ 3}})。否则,您需要以编程方式构造格式字符串以包括字段宽度。
您也执行free(pstring)
,这是无效的,因为您自己没有分配pstring
,所以它是一个数组。您确实需要遍历数组pstring
和free
中的所有字符串。尝试将malloc
(等)未返回的指针传递给free
也会导致未定义的行为。
最后,在C中,您this scanf
and family reference。