繁体   English   中英

C-将realloc与字符串指针合并

[英]C- Incorporating realloc with string pointers

我正在研究有关使用动态内存分配修改字符串的问题。 我的代码的适用部分如下:

./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:

一个主要问题是如何读取字符串:

scanf("%s", &pstring[b])

这里的pstring[b]类型为char * ,由于malloc调用,它指向某个内存(除非malloc失败,您忘记检查了)。

但是 &pstring[b]是指向该指针的指针 ,其类型为char ** 这几乎不是您想要的,并且将导致scanf在不应该写入的位置写入内存,甚至可能超出分配的内存范围。 这当然会导致不确定的行为

解决该问题后,您需要记住C中的char字符串实际上称为以null终止的 字节字符串 空终止符是所有标准字符串函数所要查找的内容,以查找字符串的结尾。 当然,这意味着x字符的字符串需要x + 1空间以适合终止符。 因此,如果用户说他或她想要一个长度为6的字符串(例如),然后将foobar作为输入,则需要使用终止符将其容纳7字符。 您在其他地方(例如strcopy函数)也strcopy这种终结器问题(或者缺少为它分配空间)。

您的scanf调用也不会阻止用户输入比用户说的更长的字符串。 如果用户说该字符串应为3字符,但是输入foobar ,则会超出范围。 不幸的是,仅使用scanf就无法解决此问题,因为字段宽度修饰符必须是格式字符串的一部分。 您可以使用scanf_s函数来解决此问题,但是C规范没有要求它,并且需要您定义一个特定的宏以使其在实现中可用(例如,请参见此scanf和系列参考)细节)。 否则,您需要以编程方式构造格式字符串以包括字段宽度。

执行了free(pstring)这是无效的,因为您没有分配pstring本身,所以它是一个数组。 您确实需要遍历数组pstring 的所有字符串并free它们。 试图将未由malloc返回的指针(等)传递给free也会导致未定义的行为

最后,在C语言中,您不应该转换malloc (和相关函数)的结果

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM