gpt4 book ai didi

c - 如何在不继续循环的情况下显示输出?

转载 作者:行者123 更新时间:2023-11-30 21:00:47 28 4
gpt4 key购买 nike

我无法显示它不断循环的输出,我是这方面的初学者。它应该检查输入是字母还是数字并将其存储为标识符,如果运算符将存储为符号并检查输入的关键字。

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

void keyword(char str[10])
{
if(strcmp("for",str)==0||strcmp("while",str)==0||strcmp("do",str)==0||strcmp("int",str)==0||strcmp("float",str)==0||strcmp("char",str)==0||strcmp("double",str)==0||strcmp("static",str)==0||strcmp("switch",str)==0||strcmp("case",str)==0)
printf("\n%s is a keyword",str);
else
printf("\n%s is an identifier",str);
}

main()
{
FILE *f1,*f2,*f3;
char c,str[10],st1[10];
int num[100], lineo=0,tokenvalue=0,i=0,j=0,k=0;
printf("\nEnter the c program ");
gets(st1);
f1=fopen("input","w");
while((c=getchar())!=EOF)
putc(c,f1);
fclose(f1);
f1=fopen("input","r");
f2=fopen("identifier","w");
f3=fopen("specialchar","w");
while((c=getc(f1))!=EOF)
{
if(isdigit(c))
{
tokenvalue=c-'0';
c=getc(f1);
while(isdigit(c))
{
tokenvalue*=10+c-'0';
c=getc(f1);
}
num[i++]=tokenvalue;
ungetc(c,f1);
}
else if(isalpha(c))
{
putc(c,f2);
c=getc(f1);
while(isdigit(c)||isalpha(c)||c=='_'||c=='$')
{
putc(c,f2);
c=getc(f1);
}
putc(c,f2);
ungetc(c,f1);
}
else if(c==' '||c=='\t')
printf("");
else if(c=='\n')
lineo++;
else
putc(c,f3);
}
fclose(f2);
fclose(f3);
fclose(f1);
printf("\nThe no. im the program are");
for(j=0;j<i;j++)
printf("%d",num[j]);
printf("\n");
f2=fopen("identifier","r");
k=0;
printf("The keywords and identifiers are: ");
while((c=getc(f2))!=EOF)
{
if(c!='\0')
str[k++]=c;
else
{
str[k]='\0';
keyword(str);
k=0;
}
}
fclose(f2);
f3=fopen("specialchar","r");
printf("\nSpecial Characters are: ");
while((c=getc(f3))!=EOF)
printf("%c",c);
printf("\n");
fclose(f3);
printf("Total no. of lines are:%d",lineo);
}

最佳答案

整个代码中有很多微妙的语法误用等。我试图找出所有问题并在评论中注明问题的性质。

从整体角度来看,最大的缺点是没有验证您的文件操作。您必须验证 fopen 是否成功, --- 在尝试从中读取字符之前。对文件进行写入之后的fclose也是如此,以确保关闭器上不存在流错误,从而使字符未写入文件。 (如果您只是从文件中读取,则通常不需要关闭时进行验证。)

当声明字符数组来保存字符串时,您应该使用 0 初始化所有元素(使用 nul-termination 字符有效地填充数组,以确保您的字符串始终为 < em>nul-termerated只要你不写超出数组的末尾即可。它很简单而且简短。就像 char str[10] = "", st1[10] = 一样简单""; 就是您所需要的。(按照惯例,如果您用值填充数组或结构的第一个元素,则默认情况下所有其他元素都会初始化为。)

还有其他微妙之处。您可以在整个过程中混合使用 getcfgetc。虽然这可以正常工作,但请注意 getc 通常作为宏实现,并且不能保证 fgetc 所做的单遍操作。

这就是概述,浏览代码,然后打开代码。您可能认为所有内容都挤在一起是可读的,但如果您考虑一下代码块之间的空行,就像书写段落一样,它肯定会使流程更容易理解。

将它们放在一起,您可以执行以下操作:

<小时/>

注意:根据您的评论进行编辑,更正了最初 Unresolved 读取逻辑错误。

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

/* use constants, not 'magic numbers' in code */
enum { MAXC = 10, MAXND = 100, MAXFN = 4096 };

void keyword (char *str)
{
if (strncmp ("for", str, strlen ("for")) == 0 ||
strncmp ("while", str, strlen ("while")) == 0 ||
strncmp ("do", str, strlen ("do")) == 0 ||
strncmp ("int", str, strlen ("int")) == 0 ||
strncmp ("float", str, strlen ("float")) == 0 ||
strncmp ("char", str, strlen ("char")) == 0 ||
strncmp ("double", str, strlen ("double")) == 0 ||
strncmp ("static", str, strlen ("static")) == 0 ||
strncmp ("switch", str, strlen ("switch")) == 0 ||
strncmp ("case", str, strlen ("case")) == 0)
printf (" keyword : %s\n", str);
else
printf (" identifier : %s\n", str);
}

int main (void) /* main() is type int, and returns a value */
{
FILE *f1, *f2, *f3;
char str[MAXC] = "", st1[MAXFN] = ""; /* initialize arrays 0 */
int c, num[MAXND] = {0}, lineo = 0, tokenvalue = 0, i = 0, j = 0, k = 0;

printf ("\nEnter the c program: ");
if (!fgets (st1, 10, stdin)) {
fprintf (stderr, "error: invalid input 'st1'\n");
return 1;
}

if (!(f2 = fopen ("input", "w"))) { /* validate opening */
fprintf (stderr, "error: file open failed 'input'.\n");
return 1;
}
/* The while takes input from stdin and writes to f1, but has nothing
* to do with the file you opened "input". I'm guessing you want to
* read file stream f1 (copy it) into "input" so you can reopen it
* in "r" mode and check for identifiers, keywords, etc.
*
* You cannot redirect a file to your code, and then prompt for
* a filename -- fgets will take the code as your filename
* (or as much will fit) because stdin is FIFO, not LIFO
*
while ((c = getchar ()) != '\n' && c != EOF)
fputc (c, f1);
*/

if (!(f1 = fopen (st1, "r"))) { /* validate opening */
fprintf (stderr, "error: file open failed '%s'.\n", st1);
return 1;
}

while ((c = fgetc (f1)) != EOF) /* you should really do this with fgets */
fputc (c, f2); /* and read/write a line at a time */

fclose (f1);

if (fclose (f2)) { /* validate close after *write*, stream error */
fprintf (stderr, "error: on stream close after write 'f2'.\n");
return 1;
}

if (!(f1 = fopen ("input", "r"))) { /* validate opening */
fprintf (stderr, "error: invalid input 'input'\n");
return 1;
}
if (!(f2 = fopen ("identifier", "w"))) { /* validate opening */
fprintf (stderr, "error: invalid input 'identifier'\n");
return 1;
}
if (!(f3 = fopen ("specialchar", "w"))) { /* validate opening */
fprintf (stderr, "error: invalid input 'specialchar'\n");
return 1;
}

while ((c = fgetc (f1)) != EOF) {
if (isdigit (c)) {
tokenvalue = c - '0';
c = fgetc (f1); /* fgetc guarantees single evaluation */
while (isdigit (c)) {
tokenvalue *= 10 + c - '0';
c = fgetc (f1);
}
num[i++] = tokenvalue;
ungetc (c, f1);
} else if (isalpha (c)) {
fputc (c, f2);
if ((c = fgetc (f1)) && c != EOF) /* need () around assignment */
while (isdigit (c) || isalpha (c) || c == '_' || c == '$') {
putc (c, f2);
c = fgetc (f1);
}
fputc (c, f2);
ungetc (c, f1);
} else if (c == ' ' || c == '\t') /* one 'space' for a char */
putchar (' '); /* printing empty-char ?, looks like 'space' or 0 */
else if (c == '\n')
lineo++;
else
putc (c, f3);
}
if (fclose (f2)) { /* validate close after *write*, stream error */
fprintf (stderr, "error: on stream close after write 'f2'.\n");
return 1;
}
if (fclose (f3)) { /* validate close after *write*, stream error */
fprintf (stderr, "error: on stream close after write 'f3'.\n");
return 1;
}
fclose (f1);

printf ("\nThe nm. in the program are: ");
for (j = 0; j < i; j++)
printf ("%d", num[j]);
putchar ('\n'); /* no need for printf for a single 'char' */

if (!(f2 = fopen ("identifier", "r"))) { /* validate opening */
fprintf (stderr, "error: invalid input 'identifier'\n");
return 1;
}
k = 0;
printf ("The keywords and identifiers are: ");
while ((c = fgetc (f2)) != EOF) {
if (k + 1 < MAXC && c != '\0') /* you must limit chars to str len */
str[k++] = c; /* and your logic needs a rework */
else {
str[k] = 0;
keyword (str);
k = 0;
}
}
putchar ('\n');
fclose (f2);

if (!(f3 = fopen ("specialchar", "r"))) { /* validate opening */
fprintf (stderr, "error: invalid input 'specialchar'\n");
return 1;
}
printf ("\nSpecial Characters are: ");
while ((c = getc (f3)) != EOF)
printf ("%c", c);
putchar ('\n');
fclose (f3);

printf ("Total no. of lines are: %d\n", lineo);
}

我运行了一个简短的 C 文件来测试你的逻辑。你还有一些工作要做。编译它并运行您的数据,如果您有任何其他问题,请告诉我。显示您仍有工作要做的示例是:

输入文件

$ nl -ba whileit.c
1 #include <stdio.h>
2 #include <string.h>
3
4 int main (void) {
5
6 char a[] = "You are welcome",
7 b[5][20] = {{0}},
8 *pch;
9 int i = 0;
10
11 pch = strtok ( a," \t" );
12
13 while (i < 5 && pch) {
14 strcpy (b[i++], pch);
15 pch = strtok( NULL, " \t\n" );
16 }
17
18 i = 0;
19 while (*b[i]) {
20 printf( "b[%d] = %s\n", i, b[i] );
21 i++;
22 }
23
24 return 0;
25 }

示例使用/输出

$ ./bin/fopenprob

Enter the c program: whileit.c

The nm. in the program are: 52000500 // nm is correct
The keywords and identifiers are: identifier : include s
identifier : dio.h>inc
identifier : ude strin
identifier : .h>int ma
identifier : n void)ch
identifier : r a[You a
identifier : e welcome
identifier : b[pch;int
identifier : i pch str // keyword logic needs work
identifier : ok a,t"wh
identifier : le i pch)
identifier : trcpy b[i
identifier : pch)pch s
identifier : rtok(NULL
identifier : t\n"i whi
identifier : e b[i]pri
identifier : tf(b[d]s\
identifier : "i,b[i]i+


Special Characters are: #<.>#<.>(){[]="",[][]={{}},*;=;=(,"\");(<&&){([++],);=(,"\\");}=;(*[]){("[%]=%\",,[]);++;};}
Total no. of lines are: 25

写入的文件

$ nl -ba input
1 #include <stdio.h>
2 #include <string.h>
3
4 int main (void) {
5
6 char a[] = "You are welcome",
7 b[5][20] = {{0}},
8 *pch;
9 int i = 0;
10
11 pch = strtok ( a," \t" );
12
13 while (i < 5 && pch) {
14 strcpy (b[i++], pch);
15 pch = strtok( NULL, " \t\n" );
16 }
17
18 i = 0;
19 while (*b[i]) {
20 printf( "b[%d] = %s\n", i, b[i] );
21 i++;
22 }
23
24 return 0;
25 }

(为了便于阅读,在 79 个字符处手动换行 - 文件中没有:)

$ cat identifier
include stdio.h>include string.h>int main void)char a[You are welcome"b[pch;int
i pch strtok a,t"while i pch)strcpy b[i+pch)pch strtok(NULL,t\n"i while b[i]pri
ntf(b[d]s\n"i,b[i]i+return

$ cat specialchar
#<.>#<.>(){[]="",[][]={{}},*;=;=(,"\");(<&&){([++],);=(,"\\");}=;(*[]){("[%]=%\
",,[]);++;};}

如您所见,您的关键字和标识符逻辑需要工作。提示,要识别关键字和标识符,您必须确保仅将开头带有标识符的字符串发送到您的关键字函数。我已经修改了您的 keyword 函数以使用 strncmp 来测试关键字,因此您可以发送例如"for(i=0"keyword ,它会识别 "for",但必须确保 str以关键字开头。我还在您的代码中留下了额外的注释以进行改进。这应该足以让您继续前进,而无需“为您做”:)

关于c - 如何在不继续循环的情况下显示输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38842868/

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