【问题标题】:C code works on linux(geany) but not on windows(VS2008)C代码适用于linux(geany)但不适用于windows(VS2008)
【发布时间】:2014-02-16 21:54:45
【问题描述】:

我为一个程序编写了代码,其中用户输入.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' )
;
} 

【问题讨论】:

  • 您很可能需要在while 循环中检查nextcharacter 中的EOF,因为您描述的问题可能来自Win32 标准库中处理错误输入的差异。

标签: c linux windows visual-studio-2008


【解决方案1】:

Visual Studio 版本 - 您已将指针分配给本地数组 sem->s = lexeme;在 yylex() 中。因此,当调用返回到 main 时,lexeme 中的值变为 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%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' );
} 

【讨论】:

  • 这听起来很合乎逻辑,它确实有效,现在它确实打印出我所期望的。现在唯一不起作用的是它卡在 eof 之前的最后一个字符上并继续打印他。在linux中它也没有这样做 >_
  • 问题是当您在 else if ( isalpha(nextcharacter) != 0 )inside else if ( isdigit(nextcharacter) != 0 ) 条件内再次执行 nextcharacter = fgetc(fp); 时。 nextchar 的值将在 EOF 处为 -1,因为您只是在检查 isdigit 和 isalphanum,所以您没有处理它。在那里处理 -1。
猜你喜欢
  • 1970-01-01
  • 2022-10-01
  • 2022-11-21
  • 2021-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多