我为一个程序编写了代码,其中用户输入.txt
文件的名称,程序打印文件中的字母数字单词或数字(字母数字单词以字母开头,包括字母或数字)。无论如何,当使用Geany在Linux上运行时,它运行得很好,但在Visual Studio 2008上则不然(我用这个视频来允许VS2008编译c代码)。
确切的问题是,它显示的字母数字就像表情符号。还有一个无休止的循环,我认为这可能与我使用fseek
函数有关。
#include <stdio.h>
#include <ctype.h>
#include <string.h>
union semantic_info
{
char *s;
int i;
}SEMANTIC_INFO ;
int yylex(FILE *fp, union semantic_info *sem);
void WaitForEnter(void);
int main()
{
union semantic_info *ptrs;
char filename[20];
int a=0,n=0;
int k;
FILE *fp;
ptrs = &SEMANTIC_INFO;
printf("Hey you, give me a file name: n");
scanf("%s", filename);
fp = fopen(filename, "r");
do
{
k = yylex(fp, ptrs);
if( k==1 )
{
printf("%s%sn", "The type is alphanumeric and it's the: ", SEMANTIC_INFO.s);
a++;
}
else if( k==2 )
{
printf("%s%dn", "The type is arithmetic and it's the: ", SEMANTIC_INFO.i);
n++;
}
}while( k!=0 );
printf("we found %d alphanumerics and %d numbers! n", a, n);
return 0;
}
int yylex(FILE *fp, union semantic_info *sem)
{
int nextcharacter;
char lexeme[100]="";
int k=1, i=0, r=3;
nextcharacter = fgetc(fp);
if ( nextcharacter == EOF)
{
r=0;
}
else if ( isalpha(nextcharacter) != 0 )
{
lexeme[i] = (char)nextcharacter;
//printf("at position %d there is %c n", i, lexeme[i]);
while(k==1)
{
nextcharacter = fgetc(fp);
if(isalnum(nextcharacter) != 0 )
{
i++;
lexeme[i] = (char)nextcharacter;
//printf("at position %d there is %c n", i, lexeme[i]);
}
else
{
lexeme[i+1] = ' ';
k=0;
sem->s = lexeme;
r=1;
fseek(fp, -1, SEEK_CUR);
}
}
}
else if ( isdigit(nextcharacter) != 0 )
{
lexeme[i] = (char)nextcharacter;
//printf("at position %d there is %c n", i, lexeme[i]);
while(k==1)
{
nextcharacter = fgetc(fp);
if(isdigit(nextcharacter)!= 0 )
{
i++;
lexeme[i] = (char)nextcharacter;
//printf("at position %d there is %c n", i, lexeme[i]);
}
else
{
lexeme[i+1] = ' ';
k=0;
sscanf(lexeme, "%d", &sem->i);
r=2;
fseek(fp, -1, SEEK_CUR);
}
}
}
WaitForEnter();
return r;
}
void WaitForEnter(void)
{
printf("Press Enter to continue: ");
//fflush(stdout);
while ( getchar() != 'n' )
;
}
Visual Studio版本-您已经将指针分配给了一个本地数组sem->s=lexeme;yylex()内部。因此,当调用返回到main时,词法中的值将变为void。因此,您必须分配内存,然后将值从lexeme复制到sem->。按照代码中的//更改注释查看更改:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include<malloc.h>//change
union semantic_info{
char *s;
int i;
}SEMANTIC_INFO ;
int yylex(FILE *fp, union semantic_info *sem);
void WaitForEnter(void);
int main()
{
union semantic_info *ptrs;
char filename[20];
int a=0,n=0;
int k;
FILE *fp;
ptrs = &SEMANTIC_INFO;
printf("Hey you, give me a file name: n");
scanf("%s", filename);
fp = fopen(filename, "r");
do
{
k = yylex(fp, ptrs);
if( k==1 )
{
printf("%s%sn", "The type is alphanumeric and it's the: ", SEMANTIC_INFO.s);
a++;
}
else if( k==2 )
{
printf("%s%dn", "The type is arithmetic and it's the: ", SEMANTIC_INFO.i);
n++;
}
}while( k!=0 );
printf("we found %d alphanumerics and %d numbers! n", a, n);
return 0;
}
int yylex(FILE *fp, union semantic_info *sem)
{
int nextcharacter;
char lexeme[100]="";
int k=1, i=0, r=3;
nextcharacter = fgetc(fp);
if ( nextcharacter == EOF)
{
r=0;
}
else if ( isalpha(nextcharacter) != 0 )
{
lexeme[i] = (char)nextcharacter;
//printf("at position %d there is %c n", i, lexeme[i]);
while(k==1)
{
nextcharacter = fgetc(fp);
if(isalnum(nextcharacter) != 0 )
{
i++;
lexeme[i] = (char)nextcharacter;
//printf("at position %d there is %c n", i, lexeme[i]);
}
else
{
lexeme[i+1] = ' ';
k=0;
sem->s=(char *)malloc(sizeof(char)*(i+2));//change
memcpy(sem->s,lexeme, i+2);//change
//sem->s = lexeme;//change
r=1;
fseek(fp, -1, SEEK_CUR);
}
}
}
else if ( isdigit(nextcharacter) != 0 )
{
lexeme[i] = (char)nextcharacter;
//printf("at position %d there is %c n", i, lexeme[i]);
while(k==1)
{
nextcharacter = fgetc(fp);
if(isdigit(nextcharacter)!= 0 )
{
i++;
lexeme[i] = (char)nextcharacter;
//printf("at position %d there is %c n", i, lexeme[i]);
}
else
{
lexeme[i+1] = ' ';
k=0;
sscanf(lexeme, "%d", &sem->i);
r=2;
fseek(fp, -1, SEEK_CUR);
}
}
}
WaitForEnter();
return r;
}
void WaitForEnter(void){
printf("Press Enter to continue: ");
//fflush(stdout);
while ( getchar() != 'n' );
}