字符串和用户在C中输入的字符串之间的区别是什么

时间:2018-03-20 17:14:42

标签: c string scanf strdup

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

我找到并使用了:

#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我得到两行。

谢谢!

CNC中  strsep存在广告问题,详细here。谢谢大家。

7 个答案:

答案 0 :(得分:4)

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

在第二段代码中,string在传递给scanf时未初始化,因此scanf正在读取该指针中的无效值并尝试取消引用它。这会调用undefined behavior,在这种情况下会显示为崩溃。

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

char string[80];

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

 scanf("%79s",string);

答案 1 :(得分:2)

两种情况之间的差异:

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

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

  3. 第二种情况可以通过使用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);
    

    确保释放动态分配的内存。否则,程序会泄漏内存。

答案 2 :(得分:1)

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

第一个选项是静态

char string[256];

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

char *string;

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

不要忘记最后释放分配的内存

free(string);

答案 3 :(得分:0)

你没有分配所需的空间! 你必须有一个可写入的内存空间。 您可以静态地使用#34; char string [256]&#34;,或者动态分配。

在您的第一个示例中,您使用&#34; strdup&#34;这是一个malloc,但scanf不会为你分配内存。

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

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

答案 4 :(得分:0)

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

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

 char *string = malloc(50);// here malloc will allocate 50 bytes from heap

答案 5 :(得分:0)

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

答案 6 :(得分:0)

char string [13] char cp = string

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

它将无法存储13个字符的字符数组,这个数组将是13个字节,正是因为这样你才得到分段错误