3

我正在使用一小段代码来测试更大(初学者)程序的功能,但我不明白两个字符串之间的区别。

我发现并使用了:

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

int main()
{

char *string, *found;

string = strdup ("1/2/3");
printf("Orig: '%s'\n",string);

while ((found = strsep(&string,"/")) != NULL )
  printf ("%s\n",found);

return (0);
}

这一次打印一个令牌。

然后,当我尝试移动到用户输入的字符串时:

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

int main()
{
  char string[13],
  char *found, *cp = string;

  fprintf(stderr, "\nEnter string: ");
  scanf("%12s",string);
  printf("Original string: '%s'\n",string);

  while((found =  strsep(&cp,"/,-")) != NULL )
    printf("%s\n",found);

  return(0);
}

我得到一个段错误。我了解指针、数组和字符串的基础知识,但显然我遗漏了一些东西,并且希望有人告诉我它是什么!

另外-如果我更改printf("%s\n",found);printf("%i\n",found);我会返回一些垃圾整数,但总是正确的数量,例如,如果我输入1/2/3我会得到三行整数,1111/2222我会得到两行。

谢谢!

- 编辑 - 有一个附加问题,在此处strsep详细说明。谢谢大家。

4

7 回答 7

4

在第一段代码中,string分配了 的返回值strdup,它为要复制的字符串分配空间并返回指向该分配空间的指针。

在第二段代码中,string当它被传递给时未初始化scanf,因此scanf读取该指针中的无效值并尝试取消引用它。这会调用 未定义的行为,在这种情况下表现为崩溃。

您需要为用户的字符串留出空间。一个简单的方法是创建一个给定大小的数组:

char string[80];

然后告诉scanf它可以读取多少个字符:

 scanf("%79s",string);
于 2018-03-20T17:19:37.603 回答
2

两种情况的区别:

  1. 在第一种情况下string,指向由分配的有效内存,strdup而在第二种情况下,您正试图读入无效内存。

  2. 第一种情况表现良好,而第二种情况是未定义行为的原因。

第二种情况可以通过使用malloc或使用固定大小的数组为其分配内存来解决。

char *string,*found;
string = malloc(100); // Make it large enough for your need.
fprintf(stderr, "\nEnter string: ");
scanf("%99s",string);

或者

char string[100], *found;
fprintf(stderr, "\nEnter string: ");
scanf("%99s",string);

确保取消分配动态分配的内存。否则,您的程序会泄漏内存。

于 2018-03-20T17:19:50.647 回答
1

您应该为用户输入字符串分配内存。

第一个选项是静态的

char string[256];

第二个选项是动态使用malloc()函数

char *string;

string = (char*) malloc(256 * sizeof(char));
if (string == NULL)
   {
   //error
   }

最后别忘了释放分配的内存

free(string);
于 2018-03-20T17:19:25.857 回答
0

您没有分配所需的空间!您必须有一个可写入的内存空间。你可以让它静态地“char string[256]”,或者动态地分配。

在您的第一个示例中,您使用执行 malloc 的“strdup”,但 scanf 不会为您分配内存。

如果您想要所有用户输入,通常将 scanf 包装在 while 循环中,以便逐块检索用户输入。然后,每次缓冲区不足以添加块时,您都必须重新分配。

如果您只想从标准输入检索字符串而不进行任何格式检查,我强烈建议使用 fgets。

于 2018-03-20T17:19:57.320 回答
0

原因很简单。您的string变量是一个 char 指针,您需要为其分配内存来存储一个字符串。可能在您的第一种情况下strdup ("1/2/3");返回一个字符串并且您char pointer *string指向strdup函数返回的字符串,这就是您没有收到分段错误的原因第一种情况。即使在您的第一种情况下,如果输入很长的字符串,您也可能会收到分段错误。

因此,在第二个示例中为指针分配足够的内存,string如下所示,这将解决您的问题:-

 char *string = malloc(50);// here malloc will allocate 50 bytes from heap
于 2018-03-20T17:21:01.387 回答
0

在用户输入字符串的情况下,您没有为指针字符串分配内存。在第一种情况下,strdup为字符串指针分配内存,而在第二种情况下,您没有任何与导致段错误的字符串指针关联的内存。首先,使用malloc分配内存,然后使用scanf

于 2018-03-20T17:21:12.987 回答
0

字符字符串[13] 字符 cp=字符串

这里 cp 是 char 类型的变量,分配了 1 个字节的内存

它将无法存储 13 个字符的 char 数组(即 13 个字节),正因为如此,您遇到了分段错误

于 2018-03-20T18:38:52.013 回答