fgets() 在进入循环之前不断被跳过
fgets() keeps getting skipped before entering loop
一直在尝试删除角色,但对 fgets
的调用 skipped/jumped 结束了。在不同的计算机上,它可以正常运行,但由于某种原因,它会跳过并基本上跳到程序的末尾。有任何想法吗?
尝试将 r = getchar();
更改为 scanf("%c\n", &r);
。
此外,您的循环有一些错误或不一致:
- 您正在向
str[j]
分配一个指针的值。应该将 str[j+1]
的值分配给 str[j]
。
- 内循环结束应该是
len-1
然后。
j--
完全没有效果。
- 你应该在完成后以
[=19=]
结束你的字符串,否则你会打印垃圾(在我的例子中它是一堆 \n
s)。
将所有内容放在一起:
for (i = 0; i < len; i++) {
if (str[i] == r) {
for (j = i; j < len-1; j++) {
str[j] = str[j+1];
}
len--;
}
}
str[len] = '[=10=]';
printf("Sentence after removal: %s\n", str);
如果你想在读取后去掉字符串末尾的\n
,你可以这样做
str[len] = '[=11=]';
len--;
在循环之前。
你的代码中有几个问题,但我没有看到 fgets()
跳过或跳过的任何原因。 getchar()
函数从 stdin
读取下一个字符。一般我们给getchar()
函数输入的时候,输入字符然后按ENTER
键。这在输入流中留下了 \n
字符,可以被下一个调用的输入函数使用。但是在您的情况下,您没有在 getchar()
.
之后调用任何其他输入函数
[尝试在 fgets()
上方调用 getchar()
并输入为 - 输入一个字符,然后输入 ENTER
键。您会看到 fgets()
被跳过,因为它消耗了输入流 stdin
.]
中剩余的 \n
字符
问题一:
看看这个声明:
str[j] = str + 1;
因为str
是一个char
数组,str[j]
表示位置j
处的一个字符,而str + 1
是指针。因此,此分配不兼容,因为您正试图将 char *
类型分配给 char
。应该是:
str[j] = str[j + 1];
问题二:
您的代码存在逻辑问题。无法处理输入字符串中连续出现待去除字符的场景。测试您的代码输入,例如 "Hello World" [字符 l
连续出现]。您的程序输出将是 [解决问题 1 后]:
Enter a sentence:
Hello World
This is the sentence: Hello World
Enter character to remove:
l
Sentence after removal: Helo Word <==== character l not removed
您的程序无法处理这种特殊情况,因为一旦它删除了一个字符,在下一次迭代中它会从下一个字符开始。
问题三:
strlen()
return 类型是 size_t
并且您正在使用 char
类型来接收它的 return 值。相反,您应该使用 size_t
类型。
getchar()
return 类型是 int
[因为它 return 是到达输入流末尾时的特殊值 EOF
] 。您正在使用 char
类型变量来接收 getchar()
return 值。
还有一点(不是问题,但你应该注意并做好预防措施):
来自 fgets() [强调我的]:
Reads at most count - 1 characters from the given file stream and stores them in the character array pointed to by str. Parsing stops if end-of-file occurs or a newline character is found, in which case str will contain that newline character. If no errors occur, writes a null character at the position immediately after the last character written to str.
因此,传递给 fgets()
的输入缓冲区可能包含换行符 ('\n'
)。例如,如果您输入 Hello World
后跟 ENTER
键,那么输入缓冲区 str
中将包含 "Hello World\n"
。在您的情况下,这不会导致任何问题,但很少有额外的循环迭代。您可以像这样从 str
缓冲区中删除 \n
:
fgets(str, 100, stdin);
str[strcspn(str, "\n")] = 0; // This will remove the trailing newline character from input buffer
此外,您应该检查 fgets()
return。如果失败,fgets()
returns NULL
.
把这些加在一起,你可以做到:
#include <stdio.h>
#include <string.h>
int main() {
char str[100];
size_t i, j, len;
int r;
printf("Enter a sentence: \n");
if (fgets(str, 100, stdin) == NULL) {
fprintf (stderr, ("fgets failed"));
return -1;
}
str[strcspn(str, "\n")] = 0;
printf("This is the sentence: %s\n", str);
printf("Enter character to remove: \n");
r = getchar();
/*If getchar returns EOF, no need to go through character removal logic*/
if (r != EOF) {
len = strlen(str);
i = 0;
while (str[i] != '[=14=]') {
if (str[i] == (char)r) {
for (j = i; j < len; j++) {
str[j] = str[j+1];
}
len--;
}
else
i++;
}
}
printf("Sentence after removal: %s\n", str);
return 0;
}
输出:
# ./a.out
Enter a sentence:
Hello World
This is the sentence: Hello World
Enter character to remove:
l
Sentence after removal: Heo Word
# ./a.out
Enter a sentence:
zzzzz
This is the sentence: zzzzz
Enter character to remove:
z
Sentence after removal:
# ./a.out
Enter a sentence:
aazz
This is the sentence: aazz
Enter character to remove:
a
Sentence after removal: zz
一直在尝试删除角色,但对 fgets
的调用 skipped/jumped 结束了。在不同的计算机上,它可以正常运行,但由于某种原因,它会跳过并基本上跳到程序的末尾。有任何想法吗?
尝试将 r = getchar();
更改为 scanf("%c\n", &r);
。
此外,您的循环有一些错误或不一致:
- 您正在向
str[j]
分配一个指针的值。应该将str[j+1]
的值分配给str[j]
。 - 内循环结束应该是
len-1
然后。 j--
完全没有效果。- 你应该在完成后以
[=19=]
结束你的字符串,否则你会打印垃圾(在我的例子中它是一堆\n
s)。
将所有内容放在一起:
for (i = 0; i < len; i++) {
if (str[i] == r) {
for (j = i; j < len-1; j++) {
str[j] = str[j+1];
}
len--;
}
}
str[len] = '[=10=]';
printf("Sentence after removal: %s\n", str);
如果你想在读取后去掉字符串末尾的\n
,你可以这样做
str[len] = '[=11=]';
len--;
在循环之前。
你的代码中有几个问题,但我没有看到 fgets()
跳过或跳过的任何原因。 getchar()
函数从 stdin
读取下一个字符。一般我们给getchar()
函数输入的时候,输入字符然后按ENTER
键。这在输入流中留下了 \n
字符,可以被下一个调用的输入函数使用。但是在您的情况下,您没有在 getchar()
.
之后调用任何其他输入函数
[尝试在 fgets()
上方调用 getchar()
并输入为 - 输入一个字符,然后输入 ENTER
键。您会看到 fgets()
被跳过,因为它消耗了输入流 stdin
.]
\n
字符
问题一:
看看这个声明:
str[j] = str + 1;
因为str
是一个char
数组,str[j]
表示位置j
处的一个字符,而str + 1
是指针。因此,此分配不兼容,因为您正试图将 char *
类型分配给 char
。应该是:
str[j] = str[j + 1];
问题二:
您的代码存在逻辑问题。无法处理输入字符串中连续出现待去除字符的场景。测试您的代码输入,例如 "Hello World" [字符 l
连续出现]。您的程序输出将是 [解决问题 1 后]:
Enter a sentence:
Hello World
This is the sentence: Hello World
Enter character to remove:
l
Sentence after removal: Helo Word <==== character l not removed
您的程序无法处理这种特殊情况,因为一旦它删除了一个字符,在下一次迭代中它会从下一个字符开始。
问题三:
strlen()
return 类型是 size_t
并且您正在使用 char
类型来接收它的 return 值。相反,您应该使用 size_t
类型。
getchar()
return 类型是 int
[因为它 return 是到达输入流末尾时的特殊值 EOF
] 。您正在使用 char
类型变量来接收 getchar()
return 值。
还有一点(不是问题,但你应该注意并做好预防措施):
来自 fgets() [强调我的]:
Reads at most count - 1 characters from the given file stream and stores them in the character array pointed to by str. Parsing stops if end-of-file occurs or a newline character is found, in which case str will contain that newline character. If no errors occur, writes a null character at the position immediately after the last character written to str.
因此,传递给 fgets()
的输入缓冲区可能包含换行符 ('\n'
)。例如,如果您输入 Hello World
后跟 ENTER
键,那么输入缓冲区 str
中将包含 "Hello World\n"
。在您的情况下,这不会导致任何问题,但很少有额外的循环迭代。您可以像这样从 str
缓冲区中删除 \n
:
fgets(str, 100, stdin);
str[strcspn(str, "\n")] = 0; // This will remove the trailing newline character from input buffer
此外,您应该检查 fgets()
return。如果失败,fgets()
returns NULL
.
把这些加在一起,你可以做到:
#include <stdio.h>
#include <string.h>
int main() {
char str[100];
size_t i, j, len;
int r;
printf("Enter a sentence: \n");
if (fgets(str, 100, stdin) == NULL) {
fprintf (stderr, ("fgets failed"));
return -1;
}
str[strcspn(str, "\n")] = 0;
printf("This is the sentence: %s\n", str);
printf("Enter character to remove: \n");
r = getchar();
/*If getchar returns EOF, no need to go through character removal logic*/
if (r != EOF) {
len = strlen(str);
i = 0;
while (str[i] != '[=14=]') {
if (str[i] == (char)r) {
for (j = i; j < len; j++) {
str[j] = str[j+1];
}
len--;
}
else
i++;
}
}
printf("Sentence after removal: %s\n", str);
return 0;
}
输出:
# ./a.out
Enter a sentence:
Hello World
This is the sentence: Hello World
Enter character to remove:
l
Sentence after removal: Heo Word
# ./a.out
Enter a sentence:
zzzzz
This is the sentence: zzzzz
Enter character to remove:
z
Sentence after removal:
# ./a.out
Enter a sentence:
aazz
This is the sentence: aazz
Enter character to remove:
a
Sentence after removal: zz