更喜欢在固定缓冲区中使用 fget,并确保为空终止符留出空间(并检查输入是否被截断)。
或者,您可以使用 scanf 进入固定缓冲区,并且您可以使用巧妙的技巧来确保您不会溢出固定缓冲区。或者你可以使用 '%as' 标志(如果你的编译器支持的话)。
注意,当你使用动态分配时,你需要自己清理。这就是为什么这么多人更喜欢垃圾收集语言为您执行内存清理/内务管理的原因。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
char*
checkin(char* p) {
if( !p ) return(p);
if (0 == sizeof(p) ) {
printf("error: read empty!\n");
return NULL;
}
int plen = strlen(p);
if ('\n' != p[plen - 1]) {
printf("error: input overflow (too long)!\n");
return NULL;
}
return(p);
}
char*
wrap(char* p) {
char append[] = "word";
printf("%s%s\n",append,p);
char* combined = malloc(strlen(append)+strlen(p)+1);
strcpy(combined,append);
strcat(combined,p);
printf("%s\n",combined);
return(combined);
}
// use fixed size buffer, fgets
char*
getstuff() {
char line[666];
fgets(line, sizeof(line)-1, stdin);
if( NULL == checkin(line) ) return NULL;
char* combined = wrap(line);
return combined;
}
// use fixed size buffer, dynamic scanf
char*
getstuff2() {
char line[666];
// dynamically build scanf fmt to specify input width
char scanfmt[32];
sprintf(scanfmt,"%%%lds",sizeof(line));
scanf(scanfmt,line);
char* combined = wrap(line);
return(combined);
}
// use dynamic scanf read
char*
getstuff3() {
/* does your compiler support '%as' flag?
// use scanf to automagically malloc enough space
char *aline = NULL;
scanf("%as",&aline);
char* combined = wrap(aline);
free(aline);
return(combined);
*/
return(NULL);
}
int
main() {
char* stuff = getstuff();
if( NULL != stuff ) printf("got:%s\n",stuff);
free(stuff); stuff = NULL;
char* stuff2 = getstuff2();
if( NULL != stuff2 ) printf("got:%s\n",stuff2);
free(stuff2); stuff2 = NULL;
char* stuff3 = getstuff3();
if( NULL != stuff3 ) printf("got:%s\n",stuff3);
free(stuff3); stuff3 = NULL;
}
给猫剥皮的方法有很多,我更喜欢 #37、疯狂的胶水和牙刷!