gpt4 book ai didi

c - K&R 1-24。为什么我的程序没有正确检查匹配的单引号和双引号?

转载 作者:太空狗 更新时间:2023-10-29 15:38:03 25 4
gpt4 key购买 nike

不必要的完整源代码:

#include <stdio.h>

main()
{
int c; //char read from stdin. Type is int to accomodate EOF
int x; //generic counter
int nl_counter = 1; //new line counter
int parens, brackets, braces, dubQuotes, singQuotes, comments; //stores number of unmatched pair occurences
int parenLines[99], bracketLines[99], braceLines[99], dubQuoteLines[99], singQuoteLines[99], commentLines[99]; //stores lines of unmatched pair occurences
int inParen, inBracket, inBrace, inDubQuote, inSingQuote, inComment; //checks whether reading inbetween a potentially matching pair
comments = parens = brackets = braces = dubQuotes = singQuotes = inComment = inParen = inBracket = inBrace = inDubQuote = inSingQuote = 0; //initializes whether in matching pairs to zero
for(x = 0; x < 99; x++) //initialize line occurences with zero
parenLines[x] = bracketLines[x] = braceLines[x] = dubQuoteLines[x] = singQuoteLines[x] = commentLines[x] = 0; //


//Read from stdin
while((c = getc(stdin)) != EOF)
{
if(c == '\n')
nl_counter++;


if(c == '/' && inComment == 0) //opens comment
{
c = getc(stdin);

if(c == '*')
{
inComment = 1;
commentLines[comments] = nl_counter;
comments++;
}
else if(c == '\n')
nl_counter++;
}

if(inComment == 1) //checks for close comment
{
if(c == '*')
{
c = getc(stdin);

if(c == '/')
{
inComment = 0;
comments--;
}
else if(c == '\n')
nl_counter++;
}
}


if(c == '(' && inComment == 0) //opens parenthesis
{
inParen = 1;
parenLines[parens] = nl_counter;
parens++;
}

if(inParen == 1 && inComment == 0) //checks for close parenthesis
{
if(c == ')')
{
inParen = 0;
parens--;
}
}

if(c == '[' && inComment == 0) //opens bracket
{
inBracket = 1;
bracketLines[brackets] = nl_counter;
brackets++;
}

if(inBracket == 1 && inComment == 0) //checks for close bracket
{
if(c == ']')
{
inBracket = 0;
brackets--;
}
}

if(c == '{' && inComment == 0) //opens brace
{
inBrace = 1;
braceLines[braces] = nl_counter;
braces++;
}

if(inBrace == 1 && inComment == 0) //checks for close brace
{
if(c == '}')
{
inBrace = 0;
braces--;
}
}

if(c == '\"' && inComment == 0 && inDubQuote == 0) //opens dubQuote
{
inDubQuote = 1;
dubQuoteLines[dubQuotes] = nl_counter;
dubQuotes++;
}
else if(inDubQuote == 1 && inComment == 0) //checks for close dubQuote
{
if(c == '\"')
{
inDubQuote = 0;
dubQuotes--;
}
}

if(c == '\'' && inComment == 0 && inSingQuote == 0) //opens single quote
{
inSingQuote = 1;
singQuoteLines[singQuotes] = nl_counter;
singQuotes++;
}
else if(inSingQuote == 1 && inComment == 0) //checks for close single quote
{
if(c == '\'')
{
inSingQuote = 0;
singQuotes--;
}
}
}



//display collected data
if(parens > 0)
{
for(x = 0; x < parens; x++)
printf("unmatched parenthesis on line %d\n", parenLines[x]);


printf("\n");
}

if(brackets > 0)
{
for(x = 0; x < brackets; x++)
printf("unmatched bracket on line %d\n", bracketLines[x]);


printf("\n");
}

if(braces > 0)
{
for(x = 0; x < braces; x++)
printf("unmatched brace on line %d\n", braceLines[x]);

printf("\n");
}

if(dubQuotes > 0)
{
for(x = 0; x < dubQuotes; x++)
printf("unmatched double quote on line %d\n", dubQuoteLines[x]);

printf("\n");
}

if(singQuotes > 0)
{
for(x = 0; x < singQuotes; x++)
printf("unmatched single quote on line %d\n", singQuoteLines[x]);

printf("\n");
}

if(comments > 0)
{
for(x = 0; x < comments; x++)
printf("unmatched comment on line %d\n", commentLines[x]);

printf("\n");
}


getc(stdin); //wait for input before exit
getc(stdin); //
}

减少不必要的完整源代码(直截了当):

#include <stdio.h>

main()
{
int c; //char read from stdin. Type is int to accomodate EOF
int x; //generic counter
int nl_counter = 1; //new line counter
int dubQuotes, singQuotes; //stores number of unmatched pair occurences
int dubQuoteLines[99], singQuoteLines[99]; //stores lines of unmatched pair occurences
int inDubQuote, inSingQuote; //checks whether reading inbetween a potentially matching pair
dubQuotes = singQuotes = inDubQuote = inSingQuote = 0; //initializes whether in matching pairs to zero
for(x = 0; x > 99; x++) //initialize line occurences with zero
dubQuoteLines[x] = singQuoteLines[x] = 0; //


//Read from stdin
while((c = getc(stdin)) != EOF)
{
if(c == '\n')
nl_counter++;



if(c == '\"' && inDubQuote == 0) //opens dubQuote
{
inDubQuote = 1;
dubQuoteLines[dubQuotes] = nl_counter;
dubQuotes++;
}
else if(inDubQuote == 1) //checks for close dubQuote
{
if(c == '\"')
{
inDubQuote = 0;
dubQuotes--;
}
}

if(c == '\'' && inSingQuote == 0) //opens single quote
{
inSingQuote = 1;
singQuoteLines[singQuotes] = nl_counter;
singQuotes++;
}
else if(inSingQuote == 1) //checks for close single quote
{
if(c == '\'')
{
inSingQuote = 0;
singQuotes--;
}
}
}



//display collected data
if(dubQuotes > 0)
{
for(x = 0; x < dubQuotes; x++)
printf("unmatched double quote on line %d\n", dubQuoteLines[x]);

printf("\n");
}

if(singQuotes > 0)
{
for(x = 0; x < singQuotes; x++)
printf("unmatched single quote on line %d\n", singQuoteLines[x]);

printf("\n");
}

getc(stdin); //wait for input before exit
getc(stdin); //
}

我还没有开始写转义序列,但是,我仍然不明白为什么所有的方括号和大括号都有效,但是如果我放一个 " 然后按回车键和 ^z(EOF),它不显示我的“第 1 行不匹配的双引号”消息。我用 if-else 和附加的 && inSingQuote == 0 补偿了它们是相同字符的事实/&& inDubQuote == 0 在对开场引号的初始检查中。我只是没有看到逻辑中的任何漏洞..

最佳答案

当遇到换行符时,您忘记将标志 inDubQuote 重置为 0。因此,当出现错误时,该标志会转移到​​下一行,并且第一个双引号会重置它,而下一个(正确关闭的)将为 that 行添加一个错误标志反而。

添加了简单的逐行调试 printf(以及为 if 提议的更简单的结构),看起来添加解决了它:

printf ("(%d)", nl_counter);

//Read from stdin
while((c = getc(stdin)) != EOF)
{
if(c == '\n')
{
inDubQuote = 0;
nl_counter++;
printf ("(%d)", nl_counter);
}


if(c == '\"')
{
if (inDubQuote == 0) //opens dubQuote
{
inDubQuote = 1;
dubQuoteLines[dubQuotes] = nl_counter;
printf ("I just set #%d to %d!\n", dubQuotes, nl_counter);
dubQuotes++;
}
else //checks for close dubQuote
{
inDubQuote = 0;
dubQuotes--;
printf ("I just reset counter to #%d!\n", dubQuotes);
}
}

}

对于一些随机输入,它的行为符合预期:

~/Documents $ ./a.out
(1)a"bc"d
i just set #0 to 1!
i just reset counter to #0!
(2)e"f"g"h
i just set #0 to 2!
i just reset counter to #0!
i just set #0 to 2!
(3)i"j"k"l"m
i just set #1 to 3!
i just reset counter to #1!
i just set #1 to 3!
i just reset counter to #1!
(4)n"o"p"q
i just set #1 to 4!
i just reset counter to #1!
i just set #1 to 4!
(5)r"s"t"u"v
i just set #2 to 5!
i just reset counter to #2!
i just set #2 to 5!
i just reset counter to #2!
(6)^D
unmatched double quote on line 2
unmatched double quote on line 4

您可以对单引号执行相同的操作,但请注意,它不会使用嵌套 级别的单引号和双引号(以及您过多的其他开始/结束标记)正确标记错误。如果你想这样做,你需要一小堆字符,你可以在上面“推”和“弹出”所有不同的字符;然后当你为一对你还没有“推”它的地方“弹出”一个时,你会标记一个错误——在一行的末尾,这个堆栈应该是空的。

关于c - K&R 1-24。为什么我的程序没有正确检查匹配的单引号和双引号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33670826/

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