我在一些脚本语言方面相当称职,但我终于强迫自己学习原始C.我只是在玩一些基本的东西(I/O现在).如何分配堆内存,将字符串存储在已分配的内存中,然后将其吐出来?这就是我现在所拥有的,我怎样才能让它正常工作?
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *toParseStr = (char*)malloc(10);
scanf("Enter a string",&toParseStr);
printf("%s",toParseStr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
目前我得到的奇怪的输出就像'8'\'.
您需要提供scanf转换格式,以便它知道您想要读取字符串 - 现在,您只是显示您分配的内存中发生的任何垃圾.而不是试图描述所有问题,这里的一些代码至少应该接近工作:
char *toParseStr = malloc(10);
printf("Enter a string: ");
scanf("%9s", toParseStr);
printf("\n%s\n", toParsestr);
/* Edit, added: */
free(toParseStr);
return 0;
Run Code Online (Sandbox Code Playgroud)
编辑:在这种情况下,free字符串没有任何真正的区别,但正如其他人所指出的,尽管如此,培养是一种好习惯.
char *toParseStr = (char*)malloc(10);
printf("Enter string here: ");
scanf("%s",toParseStr);
printf("%s",toParseStr);
free(toParseStr);
Run Code Online (Sandbox Code Playgroud)
首先,字符串in scanf指定它将要接收的输入.要在接受键盘输入之前显示字符串,请使用printf如图所示.
其次,您不需要取消引用,toParseStr因为它指向了您分配的大小为10的字符数组malloc.如果您使用的功能会将其指向另一个内存位置,则 &toParseStr需要.
例如,假设您要编写一个函数来分配内存.那么你需要&toParseStr因为你正在改变指针变量的内容(这是内存中的一个地址---你可以通过打印它的内容来亲眼看到).
void AllocateString(char ** ptr_string, const int n)
{
*ptr_string = (char*)malloc(sizeof(char) * n);
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它接受char ** ptr_string哪个读取作为指针存储指针的内存位置,该指针将存储malloc分配的n字节块的第一个字节的内存地址(在操作之后)(现在它具有一些垃圾内存地址)因为它是未初始化的).
int main(int argc, char *argv[])
{
char *toParseStr;
const int n = 10;
printf("Garbage: %p\n",toParseStr);
AllocateString(&toParseStr,n);
printf("Address of the first element of a contiguous array of %d bytes: %p\n",n,toParseStr);
printf("Enter string here: ");
scanf("%s",toParseStr);
printf("%s\n",toParseStr);
free(toParseStr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
第三,建议释放你分配的内存.即使这是你的整个程序,并且当程序退出时这个内存将被释放,这仍然是很好的做法.
使用scanf()(或fscanf()在您无法控制的数据上)与标准的“%s”说明符是一种近乎确定的方法,可以让您陷入缓冲区溢出的麻烦。
典型的例子是,如果我在你的程序中输入字符串“这个字符串超过 10 个字符”,就会出现混乱,猫狗会开始睡在一起,裸奇点很可能会出现并吞噬地球(大多数人只是陈述“未定义的行为”,但我认为我的描述更好)。
我积极阻止使用无法提供保护的功能。我会敦促您(尤其是作为 C 的新手)使用它fgets()来读取您的输入,因为您可以使用它更轻松地控制缓冲区溢出,并且它比scanf().
一旦你有了一条线,你就可以调用sscanf()它来满足你的内心需求,顺便说一句,在这种特殊情况下你不需要这样做,因为无论如何你只得到一个原始字符串。
我会用:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFSZ 10
int main(int argc, char *argv[]) {
char *toParseStr = malloc(BUFFSZ+2);
if (toParseStr == NULL) {
printf ("Could not allocate memory!\n");
return 1;
}
printf ("Enter a string: ");
if (fgets (toParseStr, BUFFSZ+2, stdin) == NULL) {
printf ("\nGot end of file!\n");
return 1;
}
printf("Your string was: %s",toParseStr);
if (toParseStr[strlen (toParseStr) - 1] != '\n') {
printf ("\nIn addition, your string was too long!\n");
}
free (toParseStr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)