scanf() 在 for 循环中不能正常工作
scanf() not working correctly within for loop
我正在尝试将多个字符串从标准输入存储到一个临时变量中。
每个字符串将在换行符之后输入。
这是我的尝试:
#include <stdio.h>
int main() {
for (int i=0; i<10; i++) {
char string;
scanf("%s\n", &string);
printf("%d\n", i);
}
}
for 循环没有按预期 运行,它只循环两次,似乎 scanf 干扰了循环。
标准输入:
test
test
标准输出:
7631717
有没有一种方法可以将标准输入中的 input/each 行动态存储到 char
变量中,而无需固定 size/length?
char string;
不是字符串而是单个字符。只要输入至少一个字符,就将格式为 %s
的字符串读入单个字符是未定义的行为。这是因为字符串终止字符也会被附加。
写...
char string[100];
scanf("%99s", string);
一切都会好起来的。
顺便说一句:如果你打算阅读完整的行(包括开头、中间和结尾的空格),请考虑使用 fgets
而不是 scanf
。
要不限于给定大小读取字符串,您可以使用修饰符 'm' :
char * p;
if (scanf("%ms", &p) == 1) {
...use p;
free(p); /* when stop to be usefull
}
来自 scanf
的人:
An optional 'm' character. This is used with string conversions (%s, %c, %[), and
relieves the caller of the need to allocate a corresponding buffer to hold the
input: instead, scanf() allocates a buffer of sufficient size, and assigns the
address of this buffer to the corresponding pointer argument, which should be a
pointer to a char * variable (this variable does not need to be initialized before
the call). The caller should subsequently free(3) this buffer when it is no longer
required.
以前的方法允许红色 'word',以读取整行,在开头删除空格(' '、换行符、制表符 ...):
#include <stdio.h>
#include <stdlib.h>
int main()
{
char * p;
if (scanf(" %m[^\n]", &p) == 1) {
printf("'%s'\n", p);
free(p);
}
else
puts("error (EOF...)");
return 0;
}
编译执行:
/tmp % gcc -Wall c.c
/tmp % ./a.out
aze qsd
'aze qsd'
/tmp % ./a.out < /dev/null
error (EOF...)
/tmp %
如果您没有该修饰符(不是 posix ...)来按原样阅读整行,您可以这样做:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char * p = malloc(1);
size_t len = 0;
int c;
while (((c = getchar()) != '\n') && (c != EOF)) {
p = realloc(p, len+1);
if (p == NULL) {
puts("not enough memory");
return -1;
}
p[len++] = c;
}
p[len] = 0;
printf("'%s'\n", p);
free(p);
return 0;
}
编译与执行:
/tmp % gcc -Wall c.c
/tmp % ./a.out
aze qsd
' aze qsd'
/tmp % ./a.out < /dev/null
''
/tmp %
Is there a way to store input/each line from stdin dynamically into a char variable without a fixed size/length?
如果愿意走 POSIX 路线,请使用 getline()
来“动态存储来自标准输入的 input/each 行”。
如果需要,删除潜在的尾随换行符
char *line = NULL;
size_t len = 0;
ssize_t nread;
while ((nread = getline(&line, &len, stdin)) != -1) {
if (nread > 0 && line[nread-1] == '\n') line[--nread] = 0;
printf("Retrieved line of length %zu: <%s>\n", nread, line);
}
free(line);
我怀疑 nread > 0 && line[nread-1] == '\n'
可以减少到 line[nread-1] == '\n'
因为我看不到 nread
returns 0.
的情况
我正在尝试将多个字符串从标准输入存储到一个临时变量中。
每个字符串将在换行符之后输入。
这是我的尝试:
#include <stdio.h>
int main() {
for (int i=0; i<10; i++) {
char string;
scanf("%s\n", &string);
printf("%d\n", i);
}
}
for 循环没有按预期 运行,它只循环两次,似乎 scanf 干扰了循环。
标准输入:
test
test
标准输出:
7631717
有没有一种方法可以将标准输入中的 input/each 行动态存储到 char
变量中,而无需固定 size/length?
char string;
不是字符串而是单个字符。只要输入至少一个字符,就将格式为 %s
的字符串读入单个字符是未定义的行为。这是因为字符串终止字符也会被附加。
写...
char string[100];
scanf("%99s", string);
一切都会好起来的。
顺便说一句:如果你打算阅读完整的行(包括开头、中间和结尾的空格),请考虑使用 fgets
而不是 scanf
。
要不限于给定大小读取字符串,您可以使用修饰符 'm' :
char * p;
if (scanf("%ms", &p) == 1) {
...use p;
free(p); /* when stop to be usefull
}
来自 scanf
的人:
An optional 'm' character. This is used with string conversions (%s, %c, %[), and relieves the caller of the need to allocate a corresponding buffer to hold the input: instead, scanf() allocates a buffer of sufficient size, and assigns the address of this buffer to the corresponding pointer argument, which should be a pointer to a char * variable (this variable does not need to be initialized before the call). The caller should subsequently free(3) this buffer when it is no longer required.
以前的方法允许红色 'word',以读取整行,在开头删除空格(' '、换行符、制表符 ...):
#include <stdio.h>
#include <stdlib.h>
int main()
{
char * p;
if (scanf(" %m[^\n]", &p) == 1) {
printf("'%s'\n", p);
free(p);
}
else
puts("error (EOF...)");
return 0;
}
编译执行:
/tmp % gcc -Wall c.c
/tmp % ./a.out
aze qsd
'aze qsd'
/tmp % ./a.out < /dev/null
error (EOF...)
/tmp %
如果您没有该修饰符(不是 posix ...)来按原样阅读整行,您可以这样做:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char * p = malloc(1);
size_t len = 0;
int c;
while (((c = getchar()) != '\n') && (c != EOF)) {
p = realloc(p, len+1);
if (p == NULL) {
puts("not enough memory");
return -1;
}
p[len++] = c;
}
p[len] = 0;
printf("'%s'\n", p);
free(p);
return 0;
}
编译与执行:
/tmp % gcc -Wall c.c
/tmp % ./a.out
aze qsd
' aze qsd'
/tmp % ./a.out < /dev/null
''
/tmp %
Is there a way to store input/each line from stdin dynamically into a char variable without a fixed size/length?
如果愿意走 POSIX 路线,请使用 getline()
来“动态存储来自标准输入的 input/each 行”。
如果需要,删除潜在的尾随换行符
char *line = NULL;
size_t len = 0;
ssize_t nread;
while ((nread = getline(&line, &len, stdin)) != -1) {
if (nread > 0 && line[nread-1] == '\n') line[--nread] = 0;
printf("Retrieved line of length %zu: <%s>\n", nread, line);
}
free(line);
我怀疑 nread > 0 && line[nread-1] == '\n'
可以减少到 line[nread-1] == '\n'
因为我看不到 nread
returns 0.