使用 scanf 将输入读入字符指针
Reading input input into a char pointer with scanf
我想在这里做的是,我想使用 scanf 将用户的输入读取到字符指针中,并在读取更多输入时动态分配内存。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *ptr, temp;
int i, ind = 0;
ptr = malloc(sizeof(char) * 2);
while (scanf(" %[^\n]c", &temp) != EOF)
{
ptr[ind] = temp;
ind++;
ptr = realloc(ptr, sizeof(char) * (ind + 1));
}
for (i = 0; i < 5; i++)
printf("%c", *(ptr + i));
return 0;
}
我的代码是这样的,但是它要么抛出一个分段错误(当一行中的字符数超过 8 个时),要么甚至不打印任何字符。我错过了什么?提前致谢。
scanf(" %[^\n]c", &temp)
不读取非换行符 ('\n'
)。 [
本身就是一个转换说明符,c
不与之匹配。
%[^\n]
表示读取任意数量的字符,直到看到换行符。 c
不是转换的一部分,它的存在会导致 scanf
.
中的匹配失败
要读取一个不是换行符的字符,请使用 %1[^\n]
,如 scanf(" %1[^\n]", &temp);
另一种解决方案是:
- 在 scanf 中使用
%c
。然后测试字符,如果是换行符就忽略。
- 更改代码以使用
getchar
而不是 scanf
。
避免使用 scanf(...) != EOF
进行测试。 scanf
returns EOF
仅当输入失败发生在第一次转换完成之前。否则,它 returns 分配的输入项数。这可能适用于仅分配一项的 scanf
的简单使用。但是,一般来说,您至少要测试 scanf
是否分配了所需数量的项目 scanf(...) == 1
。更好的方法是保存 return 值并处理多个可能的 returns:EOF
,一个小于所需项目数或所需项目数的数字。
添加到 Eric 的回答中,如果没有 scanf()
,您的代码可能会更好。这是一个 getchar()
解决方案:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int c = 0; /* int so it can hold the EOF value */
size_t ind = 0, i = 0;
char *buff = NULL, *tmp = NULL;
buff = malloc(2); /* sizeof char is 1 */
if (buff == NULL) /* malloc failed */
{
exit(EXIT_FAILURE);
}
while (1)
{
c = getchar();
if (c == EOF || c == '\n')
{
break;
}
buff[ind++] = (char)c; /* maybe check for overflow here, for non ascii characters */
/* can use ctype functions or just manually compare with CHAR_MIN and CHAR_MAX */
tmp = realloc(buff, ind + 2);
if (tmp == NULL) /* reallloc failed */
{
fprintf(stderr,"Out of memory\n");
exit(EXIT_FAILURE);
}
buff = tmp;
}
/* --------- NULL terminate if you are looking for a string */
/* buff[ind] = 0; */
/* --------------------------------------------------------- */
for (; i < ind; i++)
{
putchar(*(buff + i));
}
free(buff);
return 0;
}
我想补充一点,多次 realloc()
调用并不是一个足够的练习。更好的方法是,最初使用 malloc()
分配 X 内存量,如果您需要更多内存,则使用适当大小的 realloc()
。
我想在这里做的是,我想使用 scanf 将用户的输入读取到字符指针中,并在读取更多输入时动态分配内存。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *ptr, temp;
int i, ind = 0;
ptr = malloc(sizeof(char) * 2);
while (scanf(" %[^\n]c", &temp) != EOF)
{
ptr[ind] = temp;
ind++;
ptr = realloc(ptr, sizeof(char) * (ind + 1));
}
for (i = 0; i < 5; i++)
printf("%c", *(ptr + i));
return 0;
}
我的代码是这样的,但是它要么抛出一个分段错误(当一行中的字符数超过 8 个时),要么甚至不打印任何字符。我错过了什么?提前致谢。
scanf(" %[^\n]c", &temp)
不读取非换行符 ('\n'
)。 [
本身就是一个转换说明符,c
不与之匹配。
%[^\n]
表示读取任意数量的字符,直到看到换行符。 c
不是转换的一部分,它的存在会导致 scanf
.
要读取一个不是换行符的字符,请使用 %1[^\n]
,如 scanf(" %1[^\n]", &temp);
另一种解决方案是:
- 在 scanf 中使用
%c
。然后测试字符,如果是换行符就忽略。 - 更改代码以使用
getchar
而不是scanf
。
避免使用 scanf(...) != EOF
进行测试。 scanf
returns EOF
仅当输入失败发生在第一次转换完成之前。否则,它 returns 分配的输入项数。这可能适用于仅分配一项的 scanf
的简单使用。但是,一般来说,您至少要测试 scanf
是否分配了所需数量的项目 scanf(...) == 1
。更好的方法是保存 return 值并处理多个可能的 returns:EOF
,一个小于所需项目数或所需项目数的数字。
添加到 Eric 的回答中,如果没有 scanf()
,您的代码可能会更好。这是一个 getchar()
解决方案:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int c = 0; /* int so it can hold the EOF value */
size_t ind = 0, i = 0;
char *buff = NULL, *tmp = NULL;
buff = malloc(2); /* sizeof char is 1 */
if (buff == NULL) /* malloc failed */
{
exit(EXIT_FAILURE);
}
while (1)
{
c = getchar();
if (c == EOF || c == '\n')
{
break;
}
buff[ind++] = (char)c; /* maybe check for overflow here, for non ascii characters */
/* can use ctype functions or just manually compare with CHAR_MIN and CHAR_MAX */
tmp = realloc(buff, ind + 2);
if (tmp == NULL) /* reallloc failed */
{
fprintf(stderr,"Out of memory\n");
exit(EXIT_FAILURE);
}
buff = tmp;
}
/* --------- NULL terminate if you are looking for a string */
/* buff[ind] = 0; */
/* --------------------------------------------------------- */
for (; i < ind; i++)
{
putchar(*(buff + i));
}
free(buff);
return 0;
}
我想补充一点,多次 realloc()
调用并不是一个足够的练习。更好的方法是,最初使用 malloc()
分配 X 内存量,如果您需要更多内存,则使用适当大小的 realloc()
。