gpt4 book ai didi

c - 使用 fgets 错误通过标准输入读取输入

转载 作者:太空宇宙 更新时间:2023-11-04 03:19:52 26 4
gpt4 key购买 nike

对于类,我必须编写一段代码来检查平衡括号。输入将通过 stdin 给出(运行为:code.exe < in.txt)

输入格式如下:

CASE 1: (())
CASE 2: [})(
CASE n: ...
***end***

我是这样写的:

int main(void) {
char test[200];
char str[200];
char end[] = "***end***";
int caseNo = 1;
int j;
int flag;

while(1) {
if(strcmp(fgets(test, 200, stdin), end) == 0) {
break;
} else {
strcpy(str, test);
int len = strlen(str);
for(int i = 0; i < len; i++) {
if(str[i] == ':') {
j = i + 2;
break;
}
}

flag = balanced_parenthesis(str, j);

if(flag == 0) {
printf("CASE %d: NOT BALANCED\n", caseNo);
} else if(flag == 1) {
printf("CASE %d: BALANCED\n", caseNo);
}
caseNo++;
}
}

但是,出来的输出是错误的。我已经分别检查了我的 balanced_pa​​renthesis 函数,它确实有效,这让我相信错误出在读取输入上。

我是不是用错了 fgets 或 strcmp?有没有更好的方法来读取输入?


编辑:

完整代码如下:

#include <stdio.h>
#include <string.h>

int top = -1;
char stack[200];

void push(char c) {
top++;
stack[top] = c;
}

char pop() {
return(stack[top--]);
}

int pairs(char open, char close) {
if(open == '(' && close == ')') {
return 1;
} else if (open == '[' && close == ']') {
return 1;
} else if (open == '{' && close == '}') {
return 1;
}
return 0;
}

int balanced_parenthesis(char str[], int j) {
int len = strlen(str);
for(int i = j; i < len; i++) {
if((str[i] == '(') || (str[i] == '[') || (str[i] == '{')) {
push(str[i]);
}
if((str[i] == ')') || (str[i] == ']') || (str[i] == '}')) {
if(top == -1) { //empty
return 0;
} else {
char temp = pop();
if(pairs(temp, str[i]) == 0) {
return 0; //not pairs
}
}
}
}

if(top == -1) {
return 1; //balanced
} else {
return 0; //not balanced
}
}

int main(void) {
char test[200];
char str[200];
char end[] = "***end***";
int caseNo = 1;
int j;
int flag;

while(1) {
if(fgets(test, 200, stdin) == NULL) {
break;
} else {
test[strcspn(test, "\n")] = '\0';
if(strcmp(test, end) == 0) {
break;
} else {
strcpy(str, test);
int len = strlen(str);
for(int i = 0; i < len; i++) {
if(str[i] == ':') {
j = i + 2;
break;
}
}

flag = balanced_parenthesis(str, j);

if(flag == 0) {
printf("CASE %d: NOT BALANCED\n", caseNo);
} else if(flag == 1) {
printf("CASE %d: BALANCED\n", caseNo);
}
caseNo++;
}
}
}
}

示例输入:

CASE 1: ([[]{()}])()
CASE 2: ()[]{}
CASE 3: (([[]))
CASE 4: (()}
CASE 5: (()()()())
CASE 6: (((())))
CASE 7: (()((())()))
CASE 8: ((((((())
CASE 9: ()))
CASE 10: (()()(()
CASE 11: ][
CASE 12: ({)}
***end***

预期输出:

CASE 1: BALANCED
CASE 2: BALANCED
CASE 3: NOT BALANCED
CASE 4: NOT BALANCED
CASE 5: BALANCED
CASE 6: BALANCED
CASE 7: BALANCED
CASE 8: NOT BALANCED
CASE 9: NOT BALANCED
CASE 10: NOT BALANCED
CASE 11: NOT BALANCED
CASE 12: NOT BALANCED

最佳答案

您的代码中存在逻辑缺陷:-

对于您希望检查的每一行 - 在此之前,您必须确保重置堆栈的状态。那是你没有做的导致了问题。

void stack_reset(){
top = -1;
}

main()

  ...
if(strcmp(test, end) == 0) {
break;
} else {
reset();
strcpy(str, test);
...

此更改将使您的代码正常工作。否则它也在处理以前的状态。

因为您将 \n 作为字符数组 test 的输入,您的比较失败了。

考虑到您的其余代码没有问题,您需要做一个单一的更改才能使其正常工作。 (如果输入文件的末尾有 \n,这就是问题)。添加这个解决方案仍然很好 - 这将使这个解决方案工作,而不管文件最后一行的换行符。

while(1) {
if( !fgets(test, 200, stdin) ){
/* error handling*/
}
test[strcspn(test,"\n")]='\0';
if(strcmp(test, end) == 0) {
break;
} else {
...

您正在用 \0 覆盖 \n 因为 strcspn 返回在遇到任何指定字符之前读取的字符数在 strcspn 的第二个参数中。

此外,一旦执行了return 语句,就不会再使用break 语句,因为控制永远不会到达那个点。然后退出函数。

            if(pairs(temp, str[i]) == 0) {
return 0; //not pairs
// break; <-- not needed.
}

当输入文件以没有换行符结尾时,您接受输入的方式不会失败。如果存在,则最后一次与 ***end*** 的比较将失败。

reset() 函数与 main() 模块分开的原因是 - 如果稍后您需要更改 的实现>stack 则用户代码不会受到影响。它仍然可以调用 reset() 并确保它将重置堆栈的状态。另外作为另一个建议,尽量不要使堆栈变量 top 成为全局变量,如果您可以将结构从一个函数传递到另一个函数而不是使用全局变量,那就更好了。

关于c - 使用 fgets 错误通过标准输入读取输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47484228/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com