创建一个长缓冲区然后将 strdup 放入新变量是保存来自 scanf 的任何输入的最佳方法吗?
Is creating a long buffer and then strdup into a new variable the best way to save any input from scanf?
#include <stdio.h>
int main() {
int buf[1024];
if (scanf("%1023[^\n]", buf) == 1) {
int *myarray = strdup(buf); // strdup should use malloc to dynamically allocate basing on the length of string
if (myarray) {
printf("Value: %s\nLength of string: %d\nDynamically allocated space: %d\n", myarray, strlen(myarray), ( (strlen(myarray) + 1)*sizeof(int) )); // the last one should be the value of the new dyn allocated "myarray" array
free(myarray);
}
}
return 0;
}
这是避免 scanf 记忆问题的最佳方法吗?
我能否以某种方式使用 realloc 而不是使用 strdup 和 buf?
(strlen(myarray) + 1)*sizeof(int)
部分是否使用 strdup 正确打印动态分配的 myarray
的字节大小?
正如我在 中记录的那样,问题中的代码是一种从用户那里获取一行输入的快速而肮脏的方法,但它有一些限制:
- 如果流有空行则失败
- 长行将被静默拆分为
1023
字节块。
- 它在输入流中留下待处理的换行符。
getline
在 POSIX 系统上可用,但如果流中存在换行符,它会将换行符存储在数组的末尾。
这是 my_getline()
的一个简单实现,其行为类似于 getline
但不保留换行符:
#include <stdio.h>
#include <stdlib.h>
int my_getline(char **lineptr, size_t *n, FILE *stream) {
char *ptr = *lineptr;
size_t size = *n;
size_t pos = 0;
int c;
while ((c = getc(stream) && c != '\n') {
if (pos + 1 >= size) {
/* reallocate the array increasing size by the golden ratio */
size = size + (size / 2) + (size / 8) + 16;
ptr = realloc(ptr);
if (ptr == NULL) {
ungetc(c, stream);
return EOF;
}
*n = size;
*lineptr = ptr;
}
ptr[pos++] = c;
ptr[pos] = '[=10=]';
}
return (int)pos;
}
int main() {
char *mystring = NULL; // must be initialized
size_t size = 0; // must be initialized
int res;
while ((res = my_getline(&mystring, &size, stdin)) >= 0) {
printf("Value: %s\n"
"Length of string: %d\n",
"Allocated size: %d\n",
mystring, res, (int)size);
}
free(mystring);
return 0;
}
关于您的最后一个问题:(strlen(myarray) + 1)*sizeof(int)
部分是否正确打印了动态分配的 myarray
和 strdup
的字节大小? : 不,这个表达式不正确,没有理由乘以 sizeof(int)
。没有可移植的方法来确定 strdup()
(或 malloc
)分配的块的大小,如果分配成功,只能保证分配的大小至少为 strlen(myarray) + 1
.
#include <stdio.h>
int main() {
int buf[1024];
if (scanf("%1023[^\n]", buf) == 1) {
int *myarray = strdup(buf); // strdup should use malloc to dynamically allocate basing on the length of string
if (myarray) {
printf("Value: %s\nLength of string: %d\nDynamically allocated space: %d\n", myarray, strlen(myarray), ( (strlen(myarray) + 1)*sizeof(int) )); // the last one should be the value of the new dyn allocated "myarray" array
free(myarray);
}
}
return 0;
}
这是避免 scanf 记忆问题的最佳方法吗?
我能否以某种方式使用 realloc 而不是使用 strdup 和 buf?
(strlen(myarray) + 1)*sizeof(int)
部分是否使用 strdup 正确打印动态分配的 myarray
的字节大小?
正如我在
- 如果流有空行则失败
- 长行将被静默拆分为
1023
字节块。 - 它在输入流中留下待处理的换行符。
getline
在 POSIX 系统上可用,但如果流中存在换行符,它会将换行符存储在数组的末尾。
这是 my_getline()
的一个简单实现,其行为类似于 getline
但不保留换行符:
#include <stdio.h>
#include <stdlib.h>
int my_getline(char **lineptr, size_t *n, FILE *stream) {
char *ptr = *lineptr;
size_t size = *n;
size_t pos = 0;
int c;
while ((c = getc(stream) && c != '\n') {
if (pos + 1 >= size) {
/* reallocate the array increasing size by the golden ratio */
size = size + (size / 2) + (size / 8) + 16;
ptr = realloc(ptr);
if (ptr == NULL) {
ungetc(c, stream);
return EOF;
}
*n = size;
*lineptr = ptr;
}
ptr[pos++] = c;
ptr[pos] = '[=10=]';
}
return (int)pos;
}
int main() {
char *mystring = NULL; // must be initialized
size_t size = 0; // must be initialized
int res;
while ((res = my_getline(&mystring, &size, stdin)) >= 0) {
printf("Value: %s\n"
"Length of string: %d\n",
"Allocated size: %d\n",
mystring, res, (int)size);
}
free(mystring);
return 0;
}
关于您的最后一个问题:(strlen(myarray) + 1)*sizeof(int)
部分是否正确打印了动态分配的 myarray
和 strdup
的字节大小? : 不,这个表达式不正确,没有理由乘以 sizeof(int)
。没有可移植的方法来确定 strdup()
(或 malloc
)分配的块的大小,如果分配成功,只能保证分配的大小至少为 strlen(myarray) + 1
.