[英]Allocating string with malloc
我是 C 编程新手,现在我正在研究字符串。 我的问题是:如果我使用malloc
分配一个字符串(如下面的代码),NULL 字符是否会自动插入到字符串的末尾? 我在这里的另一个问题中找到了答案,似乎 NULL 字符没有自动包含在内。 但是问题来了:我知道如果没有 NULL 字符,像strlen
这样的函数就不起作用,在这段代码中我使用它并且它起作用。 所以我认为我的字符串末尾有\\0
,即使我没有在任何地方写它。 答案是什么?
这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv) {
char *stringa1;
int n;
int i;
printf("How many characters in the string? ");
scanf("%d", &n);
stringa1 = (char*) malloc(n*sizeof(char));
printf("Insert the string: ");
scanf("%s", stringa1);
free(stringa1);
return 0;
}
malloc()
返回一个void*
指针,指向存储在堆中的内存块。 使用malloc()
分配不会初始化任何字符串,只会占用等待占用的空间。要添加空终止字符,您必须自己执行此操作,或使用scanf()
类的函数,它会为您添加此字符。 说完这个之后,你需要事先为这个\\0
字符分配空间。
你的malloc()
调用应该是这样的:
stringa1 = (char*) malloc((n+1)*sizeof(char)); /*+1 for '\0' character */
注意:您不需要转换malloc的返回。 有关更多信息,请阅读此内容 。
另外要指出的是sizeof(char)
是1
,所以在malloc()
调用中乘以它是没有必要的。
您还需要检查malloc()
返回NULL
。 这可以这样做:
if (stringa1 == NULL) {
/* handle exit */
此外,您只能在以null结尾的字符串上使用strlen()
,否则最终会出现未定义的行为 。
一旦调用了scanf()
,并且stringa1
包含一些字符,就可以在其上调用strlen()
。
另外,检查scanf()
返回也是一个好主意。 你可以这样检查:
if (scanf("%d", &n) != 1) {
/* handle exit */
您的代码包含以下更改:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *stringa1 = NULL;
size_t n, slen;
printf("How many characters in the string? ");
if (scanf("%zu", &n) != 1) {
printf("Invalid input\n");
exit(EXIT_FAILURE);
}
stringa1 = malloc(n+1);
if (stringa1 == NULL) {
printf("Cannot allocate %zu bytes for string\n", n+1);
exit(EXIT_FAILURE);
}
printf("Insert the string: ");
scanf("%s", stringa1);
slen = strlen(stringa1);
printf("String: %s Length: %zu\n", stringa1, slen);
free(stringa1);
stringa1 = NULL;
return 0;
}
如果我使用malloc分配一个字符串(如下面的代码所示),是否在字符串末尾自动插入NULL字符?
不, malloc()
返回一块未初始化的内存。
我知道如果没有NULL字符,'strlen'之类的函数不起作用,并且在这段代码中我使用它并且它有效。 所以我认为在我的字符串末尾有'\\ 0',即使我没有在任何地方写它。
scanf()
插入空字节( '\\0'
你)当您使用%s
格式说明(假设scanf()
成功)。
来自man scanf()
:
s匹配一系列非空白字符; 下一个指针必须是指向字符数组的初始元素的指针,该字符数组的长度足以保存输入序列和终止空字节('\\ 0'),该字节是自动添加的。 输入字符串在空白处或最大字段宽度处停止,以先发生者为准。
(强调我的)。
顺便说一下,你应该对scanf()
和malloc()
调用进行错误检查。
C中“string”的定义是一个字符序列,以空字符结尾 。
要为字符串分配内存,请计算chracters(例如strlen
)并为此终止空字符添加1。
scanf
和strcpy
等函数添加空字符; 像strncpy
这样的函数并不总能这样做。
malloc
返回指向未初始化的内存范围的指针。
如果你想要用零初始化内存范围,那么你可以使用另一个标准函数calloc
而不是malloc
。
考虑到通常这样的问题
printf("How many characters in the string? ");
暗示终止零不计算在内。 所以你必须再分配一个字节的内存。 例如
stringa1 = ( char* )malloc( ( n + 1 ) *sizeof( char ) );
要么
stringa1 = ( char* )calloc( n + 1, sizeof( char ) );
在最后一种情况下,您可以应用返回0的函数strlen
,因为内存范围是零初始化的。
这个scanf
调用
scanf("%s", stringa1);
是不安全的。 最好使用fgets
代替。 例如
fgets( stringa1, n + 1, stdin );
此函数可以使用新行字符附加字符串。 要从字符串中删除它,您可以编写
stringa1[strcspn( stringa1, "\n" )] = '\0';
实现这一点的简单方法是包含 cs50 库。 只需使用 get_string 函数:
#include <stdio.h>
#include <cs50.h>
int main(void) {
// input the string to stringa1
char *stringa1 = get_string("Insert the string: ");
// call the string
printf("The string you type was: %s\n", stringa1);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.