经过几年的缺席,我已经恢复了C编码的乐趣。
我给自己做了一个练习,使用fgets()
安全地将文本从标准输入复制到字符串,然后复制到字符串足够大,即只有足够的容量才能保存没有。我实际输入的字符,最终是从头开始制作列表,堆栈等,换句话说,用指针播放。
我已经把这个 kludge 气味的唯一方法告诉了我,因为我在控制流的后期定义了strcpy()
的目标字符串变量。是否有更优雅/动态的方式来做到这一点?
#inlcude <stdio.h>
#include <string.h>
#define MAXLENGTH 20
int main(int argc, char *argv[]) {
char message[MAXLENGTH];
printf("Enter a string: \n");
fgets(message, MAXLENGTH, stdin);
/* various tests here, omitted for brevity */
char destinationString[strlen(message)];
/*
* Just testing to prove that
* the strlen() of the destination
* string is LESS than MAXLENGTH
*/
printf("Here's the strlen() of destinationString: %lu\n", strlen(destinationString));
printf("Here's the sizeof() destinationString: %lu,\n" sizeof(destinationString));
printf("Here's the contents of the copy: %s", destinationString);
return 0;
}
答案 0 :(得分:3)
您当然可以使用malloc
动态执行此操作。
考虑这样的事情:
int main(int argc, char *argv[]) {
char *destinationString;
/* ... */
/* Don't forget to allocate one extra byte for the termination character */
destinationString = malloc(strlen(message) + 1);
if (!destinationString)
return -1;
strcpy(destinationString, message);
/* Note: Normally, you should probably use strncpy to avoid overflow
but here, we're sure that there's enough space so strcpy is acceptable */
/* ... */
free(destinationString); /* When you're done using it */
/* ... */
}
我也在注释中指出了这一点,但是为了重新迭代,你实际上需要在目标字符串缓冲区中分配strlen(message) + 1
个字节,否则它会溢出。额外的字符是将空终止字符存储在C字符串的末尾。
答案 1 :(得分:0)
代码有很多选择。这是2:
malloc()
以及之后的free()
正确大小的记忆由@tangrs同样回答。请注意,sizeof() destinationString
将是指针的大小。
size_t size = strlen(message) + 1;
char *destinationString = malloc(size);
memcpy(destinationString, message, size);
使用可变长度数组VLA,可在C99中使用,也可选择在C11中使用。
使用代码清理的VLA方法
#include <string.h>
#define MAXLENGTH 20
int main(int argc, char *argv[]) {
char message[MAXLENGTH];
printf("Enter a string: \n");
if (fgets(message, sizeof message, stdin) == NULL) {
return -1;
}
// Use type `size_t`
size_t size = strlen(message) + 1;
char destinationString[size];
memcpy(destinationString, message, size);
// Notice "%zu"
// `sizeof destinationString` is the size of an array
printf("Here's the strlen() of destinationString: %zu\n", strlen(destinationString));
printf("Here's the sizeof() destinationString: %zu,\n" sizeof destinationString);
printf("Here's the contents of the copy: \"%s\"", destinationString);
return 0;
}
输入"Hello!"
输入
Here's the strlen() of destinationString: 8
Here's the sizeof() destinationString: 9,
Here's the contents of the copy: "Hello!
"
在我的系统上,输入以"\r\n"
结束。要删除那些潜在的讨厌字符的缓冲区,请使用:
fgets(message, sizeof message, stdin);
buffer[strcspn(message, "\r\n")] = '\0';
size_t size = strlen(message) + 1;
...