曾经尝试删除一个字符,但是对fgets
的调用被跳过/跳过。在不同的计算机上,它可以正常运行,但是由于某种原因,它会跳过并基本上跳到程序末尾。有任何想法吗?
答案 0 :(得分:3)
您的代码中有几个问题,但是我看不到fgets()
被跳过或跳过的任何原因。 getchar()
函数从stdin
读取下一个字符。通常,当我们为getchar()
函数提供输入时,我们输入字符并按ENTER
键。这将\n
字符留在了输入流中,可以由下一个调用的输入函数使用。但是对于您而言,您不会在getchar()
之后调用任何其他输入函数。
[尝试在getchar()
上方调用fgets()
,然后输入:-输入一个字符,然后按ENTER
键。您将看到fgets()
被跳过,因为它消耗了输入流\n
中剩余的stdin
字符。]
问题1:
看这句话:
str[j] = str + 1;
由于str
是char
数组,str[j]
代表位置j
处的字符,而str + 1
是指针。因此,此分配不兼容,因为您正在尝试将char *
类型分配给char
。应该是:
str[j] = str[j + 1];
问题2:
您的代码存在逻辑问题。它无法处理要删除的字符在输入字符串中连续出现的情况。测试您的代码是否可以输入“ 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
您的程序无法处理这种特殊情况,因为一旦删除了字符,在下一次迭代中它将从下一个字符开始。
问题3:
strlen()
返回类型为size_t
,而您正在使用char
类型接收其返回值。相反,您应该使用size_t
类型。
getchar()
的返回类型为int
[因为到达输入流的末尾时它将返回特殊值EOF
] 。您正在使用char
类型的变量来接收getchar()
的返回值。
还有一点(这不是问题,但您应该意识到这一点并采取预防措施):
来自fgets() [我的重点] :
最多读取-从给定的文件流中读取1个字符,并将它们存储在str指向的字符数组中。 如果发生文件末尾或找到换行符,分析将停止,在这种情况下,str将包含该换行符。如果没有错误,请在最后一个字符之后的位置处写入一个空字符写给str。
因此,传递给fgets()
的输入缓冲区中可能包含换行符('\n'
)。例如,如果您给输入Hello World
后跟ENTER
键,那么输入缓冲区str
将包含"Hello World\n"
。在您的情况下,这不会造成任何问题,但是循环的额外迭代很少。您可以像这样从\n
缓冲区中删除str
:
fgets(str, 100, stdin);
str[strcspn(str, "\n")] = 0; // This will remove the trailing newline character from input buffer
此外,您应该检查fgets()
返回。如果失败,fgets()
返回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] != '\0') {
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
答案 1 :(得分:1)
尝试将r = getchar();
更改为scanf("%c\n", &r);
。
此外,您的循环中存在一些错误或不一致之处:
str[j]
。应该为str[j]
分配str[j+1]
的值。len-1
。j--
完全无效。\0
s)。将所有内容放在一起:
\n
如果您想在阅读后删除字符串末尾的 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] = '\0';
printf("Sentence after removal: %s\n", str);
,可以这样做
\n
在循环之前。