我为一个程序编写了代码,用户输入了.txt
文件的名称,程序打印出文件中的字母数字或数字(字母数字单词以字母开头,包括字母或数字)。无论如何,当使用Geany在Linux上运行时,它工作正常,但在Visual Studio 2008上却没有(我使用this video来允许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%s\n", "The type is alphanumeric and it's the: ", SEMANTIC_INFO.s);
a++;
}
else if( k==2 )
{
printf("%s%d\n", "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] = '\0';
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] = '\0';
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' )
;
}
答案 0 :(得分:1)
Visual Studio版本 - 您已将指针指定为本地数组sem-&gt; s = lexeme;在yylex()里面。因此,当调用返回main时,lexeme中的值变为void。所以,你必须分配内存,然后将值从lexeme复制到sem-&gt;。按照代码中的//更改注释查看更改:
#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%s\n", "The type is alphanumeric and it's the: ", SEMANTIC_INFO.s);
a++;
}
else if( k==2 )
{
printf("%s%d\n", "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] = '\0';
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] = '\0';
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' );
}