字符串和用户在 C 中输入的字符串有什么区别
What's the difference between a string and a user entered string in C
我正在使用一小段代码来测试较大(初学者)程序的功能,但我不明白两个字符串之间的区别。
我发现并使用了:
#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
有一个额外的问题,详细 。谢谢大家
您应该为用户输入的字符串分配内存。
第一个选项是静态的
char string[256];
第二个选项是动态使用 malloc()
函数
char *string;
string = (char*) malloc(256 * sizeof(char));
if (string == NULL)
{
//error
}
最后别忘了释放分配的内存
free(string);
在第一段代码中,string
被分配了 strdup
的 return 值,它为要复制的字符串分配了 space 并且 return 是指向已分配 space.
的指针
在第二段代码中,string
在传递给 scanf
时未初始化,因此 scanf
正在读取该指针中的无效值并尝试取消引用它。这会调用 undefined behavior,在本例中表现为崩溃。
您需要为用户的字符串预留space。一个简单的方法是创建一个给定大小的数组:
char string[80];
然后告诉scanf
它能读入多少个字符:
scanf("%79s",string);
两种情况的区别:
在第一种情况下,string
指向由 strdup
分配的有效内存,而在第二种情况下,您正试图读入无效内存。
第一种情况表现良好,而第二种情况导致未定义的行为。
第二种情况可以通过使用 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);
确保释放动态分配的内存。否则,您的程序会泄漏内存。
您没有分配所需的 space!
你必须有一个内存 space 才能写入。
您可以静态地 "char string[256]" 或通过分配动态地拥有它。
在您的第一个示例中,您使用了执行 malloc 的 "strdup",但 scanf 不会为您分配内存。
如果您想要所有用户输入,通常将 scanf 包装在一个 while 循环中,以便逐块检索用户输入。然后,每次您的缓冲区不足以添加块时,您都必须重新分配。
如果你只是想从标准输入中检索一个字符串而不做任何事情 format-checking,我强烈推荐 fgets。
原因很简单。您的 string
变量是一个字符指针,您需要为其分配内存以在您的第一种情况下存储 string.Probably strdup ("1/2/3");
returns 一个字符串和您的 char pointer *string
strdup
函数指向字符串 return ,这就是为什么在第一种情况下你没有得到分段错误的原因。即使在您的第一种情况下,如果输入很长的字符串,您也可能会遇到分段错误。
因此在第二个示例中为 string
指针分配足够的内存,这将解决您的问题:-
char *string = malloc(50);// here malloc will allocate 50 bytes from heap
在用户输入字符串的情况下,您没有为指针分配内存 string.In 第一种情况,strdup 正在为字符串指针分配内存,而在第二种情况下您没有任何与导致段错误的字符串指针关联的内存。首先,使用 malloc 分配内存,然后使用 scanf。
字符串[13]
char cp=字符串
这里cp是一个char类型的变量,分配了1字节的内存
它无法存储 13 个字符的 char 数组,也就是 13 个字节,正因为如此,您会遇到分段错误
我正在使用一小段代码来测试较大(初学者)程序的功能,但我不明白两个字符串之间的区别。
我发现并使用了:
#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
有一个额外的问题,详细
您应该为用户输入的字符串分配内存。
第一个选项是静态的
char string[256];
第二个选项是动态使用 malloc()
函数
char *string;
string = (char*) malloc(256 * sizeof(char));
if (string == NULL)
{
//error
}
最后别忘了释放分配的内存
free(string);
在第一段代码中,string
被分配了 strdup
的 return 值,它为要复制的字符串分配了 space 并且 return 是指向已分配 space.
在第二段代码中,string
在传递给 scanf
时未初始化,因此 scanf
正在读取该指针中的无效值并尝试取消引用它。这会调用 undefined behavior,在本例中表现为崩溃。
您需要为用户的字符串预留space。一个简单的方法是创建一个给定大小的数组:
char string[80];
然后告诉scanf
它能读入多少个字符:
scanf("%79s",string);
两种情况的区别:
在第一种情况下,
string
指向由strdup
分配的有效内存,而在第二种情况下,您正试图读入无效内存。第一种情况表现良好,而第二种情况导致未定义的行为。
第二种情况可以通过使用 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);
确保释放动态分配的内存。否则,您的程序会泄漏内存。
您没有分配所需的 space! 你必须有一个内存 space 才能写入。 您可以静态地 "char string[256]" 或通过分配动态地拥有它。
在您的第一个示例中,您使用了执行 malloc 的 "strdup",但 scanf 不会为您分配内存。
如果您想要所有用户输入,通常将 scanf 包装在一个 while 循环中,以便逐块检索用户输入。然后,每次您的缓冲区不足以添加块时,您都必须重新分配。
如果你只是想从标准输入中检索一个字符串而不做任何事情 format-checking,我强烈推荐 fgets。
原因很简单。您的 string
变量是一个字符指针,您需要为其分配内存以在您的第一种情况下存储 string.Probably strdup ("1/2/3");
returns 一个字符串和您的 char pointer *string
strdup
函数指向字符串 return ,这就是为什么在第一种情况下你没有得到分段错误的原因。即使在您的第一种情况下,如果输入很长的字符串,您也可能会遇到分段错误。
因此在第二个示例中为 string
指针分配足够的内存,这将解决您的问题:-
char *string = malloc(50);// here malloc will allocate 50 bytes from heap
在用户输入字符串的情况下,您没有为指针分配内存 string.In 第一种情况,strdup 正在为字符串指针分配内存,而在第二种情况下您没有任何与导致段错误的字符串指针关联的内存。首先,使用 malloc 分配内存,然后使用 scanf。
字符串[13] char cp=字符串
这里cp是一个char类型的变量,分配了1字节的内存
它无法存储 13 个字符的 char 数组,也就是 13 个字节,正因为如此,您会遇到分段错误