CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Nov 2010
    Posts
    11

    My software works on Windows, but not on Linux...

    Hello man, good night. Since now I talk you I don know if this is the rightt place for this post; administration, if i am wrong, I am sorry.

    I must do a simulation, a project, of a compiler...this is just part of this, the lexic analisis. anyway, my logic is correct (at least I guess, cause it is working on windows). the problem is: my software, using visual studio c++ 2010, works fine, showing all the correct results. but, on linux, its crazy... when it begin, get in a infinite loop... why, I don know. My doubt is: looking this code, can you help me to find something that can be done on Linux? I dont know, some function that only works on Windows...

    I must give to my software a txt simulating a cpp, for example this...

    if(x==45)
    {
    z=10;
    x="maria";
    }

    the program after reading other files with the keywords supported, delimiters, operators, etc., and make appropriate comparacaoes must show the following:

    if --> keywords
    ( --> delimiters
    x --> variable
    == -> operator

    here is the code...

    PS: i am sorry if i am writing something wrong.. I am brazilian, and yet training my english :P
    PS 2: the code is in portuguese, but i think it is not problem... my problem is not in the logic (i guess), but in some function that does not works on Linux. anyway, if you want, I can translate the code, no problems.

    thank you very much.
    Murilo Marchiori
    comp.marchiori@gmail.com

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <stdio.h>
    #include <ctype.h>
    using namespace std;
    
    const int NUM=200;
    
    void carrega_txt(string vetor_operadores[NUM], string vetor_delimitadores[NUM], string vetor_reservadas[NUM]);
    void guarda_operadores(string palavra, string vetor_operadores[NUM]);
    void guarda_delimitadores(string palavra, string vetor_delimitadores[NUM]);
    void guarda_reservadas(string palavra, string vetor_reservadas[NUM]);
    int fhash(string palavra);
    int testa_numero(string line, int x);
    int testa_operador(string line, int x, string vetor_operadores[NUM]);
    int testa_delimitador(string line, int x, string vetor_delimitadores[NUM]);
    int testa_reservada(string line, string vetor_reservadas[NUM]);
    
    
    int main()
    {
    	string teste, palavra, palavra2, line, concatena, vetor_operadores[NUM], vetor_delimitadores[NUM], vetor_reservadas[NUM], recebe, recebe2, testando, auxiliar;
    	int x=0; //usado para varrer a linha toda
    	int i=0; //usado para "zerar" os vetores de string
    	int testa_funcao=0, testa_tamanho=0, z=0;
    
    	//zerando vetores
    
    	for(i=0; i<NUM; i++)
    	{
    		vetor_operadores[i] = "";
    		vetor_delimitadores[i] = "";
    	}
    
    	carrega_txt(vetor_operadores, vetor_delimitadores, vetor_reservadas);
    		
    	ifstream entrada;
    	entrada.open("programa_user.txt"); //Abre o arquivo;
    
    	if(entrada.is_open()) //Se o arquivo for aberto com sucesso...
    	{
    		while(!entrada.eof()) //Enquanto o arquivo não chegar no fim...
    		{
    			getline(entrada,line); //Copia uma linha inteira do arquivo para a string line;
    			
    			x=0;
    
    			while (x < line.size()) //x percorre a string caractere por caractere;
    			{
    				while((line.at(x) == '\t' || line.at(x) == ' ') && x < line.size())
    					x++;
    				
    				testa_funcao = testa_numero(line, x);
    
    				if(testa_funcao == 0) //ja sei que não é numero. testo, entao, se é outra coisa...
    				{
    					testa_funcao = testa_operador(line, x, vetor_operadores);
    
    					if(testa_funcao == 0)
    					{
    						//ja sei que tambem nao é operador numerico...
    						
    						testa_funcao = testa_delimitador(line, x, vetor_delimitadores);
    
    						if(testa_funcao == 0)
    						{
    							palavra = line.at(x);
    																					
    							while(isalpha(line.at(x)) && x < line.size()-1)
    							{
    								palavra = palavra + line.at(x+1);
    								x++;
    							}
    
    							testa_tamanho = palavra.size();
    
    							if(isalpha(palavra.at(testa_tamanho-1)) == 0)
    							{
    								x--;
    								//preciso agora fazer palavra receber ela mesma menos o ultimo caractere
    								
    								z=0;
    								palavra2="";
    								while(isalpha(palavra.at(z)))
    								{
    									palavra2 = palavra2 + palavra.at(z);
    									z++;
    									teste = palavra.at(z); 
    								}
    
    								palavra = palavra2;
    							}
    
    							testa_funcao = testa_reservada(palavra, vetor_reservadas);
    
    							if(testa_funcao == 0)
    							{
    								if(teste == "\"" || teste == "\'")
    									cout << "\n" << palavra << " ---- string.\n";
    								else
    									cout << "\n" << palavra << " ---- variavel.\n";
    							}
    						}
    					}
    					else
    						x=testa_funcao;
    				}
    				else
    					x=testa_funcao;
    
    				x++;
    			}
    		}
    		
    		entrada.close();
    	}
    	else 
    		cout << "Erro na leitura do arquivo\n\n";
    		
    	cout << "\n\n";
    }
    
    void carrega_txt(string vetor_operadores[NUM], string vetor_delimitadores[NUM], string vetor_reservadas[NUM])
    {
    	ifstream entrada;
    	string line;
    	
    	entrada.open("operadores_num.txt"); //Abre o arquivo;
    
    	if(entrada.is_open()) //Se o arquivo for aberto com sucesso...
    	{
    		while(!entrada.eof()) //Enquanto o arquivo não chegar no fim...
    		{
    			getline(entrada,line);
    
    			//jogo line no vetor_operadores
    			guarda_operadores(line, vetor_operadores);
    		}
    	}
    	else
    		cout << "\n\nErro durante a leitura do 'arquivo operadores_num.txt'";
    
    	entrada.close();
    	
    	//**********************************************************************************
    	
    	entrada.open("delimitadores.txt"); //Abre o arquivo;	
    
    	if(entrada.is_open()) //Se o arquivo for aberto com sucesso...
    	{
    		while(!entrada.eof()) //Enquanto o arquivo não chegar no fim...
    		{
    			getline(entrada,line);
    
    			//jogo line no vetor_operadores
    			guarda_delimitadores(line, vetor_delimitadores);
    		}
    	}
    	else
    		cout << "\n\nErro durante a leitura do arquivo 'delimitadores.txt'";
    
    	entrada.close();
    		
    	//**********************************************************************************
    	
    	entrada.open("reservadas.txt"); //Abre o arquivo;	
    
    	if(entrada.is_open()) //Se o arquivo for aberto com sucesso...
    	{
    		while(!entrada.eof()) //Enquanto o arquivo não chegar no fim...
    		{
    			getline(entrada,line);
    
    			//jogo line no vetor_operadores
    			guarda_reservadas(line, vetor_reservadas);
    		}
    	}
    	else
    		cout << "\n\nErro durante a leitura do arquivo 'reservadas.txt'";
    
    	entrada.close();
    }
    
    void guarda_operadores(string palavra, string vetor_operadores[NUM])
    {
    	int posicao = fhash(palavra);
    
    	//se a posição do vetor está vazia, simplesmente insiro o número;
    	//senão, concateno o que já está lá, através do ".", com a nova palavra.
    	
    	if(vetor_operadores[posicao]=="")
    		vetor_operadores[posicao] = palavra+".";
    	else
    		vetor_operadores[posicao] = vetor_operadores[posicao]+"."+palavra;
    }
    
    void guarda_delimitadores(string palavra, string vetor_delimitadores[NUM])
    {
    	int posicao = fhash(palavra);
    
    	//se a posição do vetor está vazia, simplesmente insiro o número;
    	//senão, concateno o que já está lá, através do ".", com a nova palavra.
    	
    	if(vetor_delimitadores[posicao]=="")
    		vetor_delimitadores[posicao] = palavra+".";
    	else
    		vetor_delimitadores[posicao] = vetor_delimitadores[posicao]+"."+palavra;
    }
    
    void guarda_reservadas(string palavra, string vetor_reservadas[NUM])
    {
    	int posicao = fhash(palavra);
    
    	//se a posição do vetor está vazia, simplesmente insiro o número;
    	//senão, concateno o que já está lá, através do ".", com a nova palavra.
    	
    	if(vetor_reservadas[posicao]=="")
    		vetor_reservadas[posicao] = palavra+".";
    	else
    		vetor_reservadas[posicao] = vetor_reservadas[posicao]+"."+palavra;
    }
    
    int fhash(string palavra)
    {
    	int sum, i;
    
    	sum=i=0;
    
    	while (i < palavra.size())
    	{
    		sum = sum + int(palavra.at(i));
    		i++;
    	}
    
    	return (sum%NUM);
    }
    
    int testa_numero(string line, int x)
    {
    	string concatena;
    
    	if(isdigit(line.at(x)))
    	{
    		concatena = line.at(x);
    				
    		//significa que "line.at(x)" é um numero.
    		if(line.at(x+1) == ',' || isdigit(line.at(x+1)))
    		{
    			//significa que line.at(x+1) é um número também, portanto line.at(x) e line.at(x+1) são parte do mesmo número.
    			while(line.at(x+1) == ',' || isdigit(line.at(x+1)))
    			{
    				concatena += line.at(x+1);
    				x++;
    			}
    			cout << "\n" << concatena << " ---- dado numerico.\n";			
    		}
    		else
    			cout << "\n" << line.at(x) << " ---- dado numerico.\n";
    		
    		return x; //retorno para a main o valor de x, ou seja, a posição de onde ele deve continuar.
    	}
    	else
    		return 0;
    
    }
    
    int testa_operador(string line, int x, string vetor_operadores[NUM])
    {
    	string recebe, testando, auxiliar, recebe2;
    	int verifica, flag=0, y=0;
    	
    	//calculo o hash do simbolo e armazeno em "recebe"
    	recebe = line.at(x);
    	verifica = fhash(recebe);
    		
    	//testando recebe o que está no vetor, na posição determinada pelo cálculo do hash	
    	testando = vetor_operadores[verifica];
    	
    	y=0;
    	
    	if(testando != "")	
    	{	
    		while (y < testando.size() && flag==0)		
    		{		
    			auxiliar="";
    			
    			while(testando.at(y) != '.')			
    			{			
    				auxiliar += testando.at(y);				
    				y++;
    			}
    
    			if(auxiliar == recebe)			
    			{			
    				flag=1;
    				
    				y=0;
    
    				recebe2 = line.at(x+1);
    				verifica = fhash(recebe2);
    				testando = vetor_operadores[verifica];
    
    				if(testando != "")
    				{
    					while (y < testando.size() && flag==1)
    					{
    						auxiliar="";
    
    						while(testando.at(y) != '.')					
    						{					
    							auxiliar += testando.at(y);						
    							y++;						
    						}
    
    						if(auxiliar == recebe2)					
    							flag = 2;						
    						else					
    							y++;
    					}
    				}			
    				
    				if(flag == 2)
    				{				
    					cout << "\n" << recebe+recebe2 << " ---- operador aritmetico.\n";
    					x++;					
    				}
    				
    				else
    					cout << "\n" << recebe << " ---- operador aritmetico.\n";					
    			}			
    			else			
    				y++;
    		}		
    	}
    
    	if(flag == 0)
    		return 0;
    	else
    		return x;
    }
    
    int testa_delimitador(string line, int x, string vetor_delimitadores[NUM])
    {
    	string recebe, testando, auxiliar, recebe2;
    	int verifica, flag=0, y=0;
    	
    	//calculo o hash do simbolo e armazeno em "recebe"
    	recebe = line.at(x);
    	verifica = fhash(recebe);
    		
    	//testando recebe o que está no vetor, na posição determinada pelo cálculo do hash	
    	testando = vetor_delimitadores[verifica];
    	
    	y=0;
    	
    	if(testando != "")
    	{	
    		while (y < testando.size() && flag==0)
    		{		
    			auxiliar="";
    			
    			while(testando.at(y) != '.')
    			{			
    				auxiliar += testando.at(y);
    				y++;
    			}
    
    			if(auxiliar == recebe)
    			{
    				cout << "\n" << recebe << " ---- delimitador.\n";
    				flag=1;
    			}
    			
    			else
    				y++;
    		}
    	}
    	
    	if(flag == 0)
    		return 0;
    	else
    	{
    		x=x+1;
    		return x;
    	}
    }
    
    int testa_reservada(string line, string vetor_reservadas[NUM])
    {
    	string recebe, testando, auxiliar, recebe2;
    	int verifica, flag=0, y=0;
    	
    	//calculo o hash do simbolo e armazeno em "recebe"
    	recebe = line;
    	verifica = fhash(recebe);
    		
    	//testando recebe o que está no vetor, na posição determinada pelo cálculo do hash	
    	testando = vetor_reservadas[verifica];
    	
    	y=0;
    	
    	if(testando != "")
    	{	
    		while (y < testando.size() && flag==0)
    		{
    			auxiliar="";
    			
    			while(testando.at(y) != '.')
    			{			
    				auxiliar += testando.at(y);
    				y++;
    			}
    
    			if(auxiliar == recebe)
    			{
    				cout << "\n" << recebe << " ---- palavra reservada.\n";
    				flag=1;
    			}
    			
    			else
    				y++;
    		}
    	}
    	
    	if(flag == 0)
    		return 0;
    	else
    		return 1;
    }

  2. #2
    Join Date
    Oct 2008
    Posts
    1,456

    Re: My software works on Windows, but not on Linux...

    I've not read all the code, but the line "while(!entrada.eof())" is wrong, causing a potential infinite loop; take a look here to see why.

  3. #3
    Join Date
    Nov 2010
    Posts
    11

    Re: My software works on Windows, but not on Linux...

    Quote Originally Posted by superbonzo View Post
    I've not read all the code, but the line "while(!entrada.eof())" is wrong, causing a potential infinite loop; take a look here to see why.
    Thanks friend, but I imagine is not this... I've used this in many programs, even on Linux, and works fine...

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: My software works on Windows, but not on Linux...

    Quote Originally Posted by Murilo Marchiori View Post
    Thanks friend, but I imagine is not this... I've used this in many programs, even on Linux, and works fine...
    Instead of imagining and guessing, use the debugger to debug your own code. If you wrote this program, then you should be using the debugger to debug it.

    What superbonzo showed you is how that statement can go wrong, regardless of whether it works in Windows.

    Regards,

    Paul McKenzie

  5. #5
    Join Date
    Nov 2010
    Posts
    11

    Re: My software works on Windows, but not on Linux...

    Quote Originally Posted by Paul McKenzie View Post
    Instead of imagining and guessing, use the debugger to debug your own code. If you wrote this program, then you should be using the debugger to debug it.

    What superbonzo showed you is how that statement can go wrong, regardless of whether it works in Windows.

    Regards,

    Paul McKenzie
    I see, I am using the debugger, and making manual tests here, but it don't show any error... if it works in windows, the logic is correct, right? that's why I can't understand... (i am using the debugger of visual studio 2010... I don't know how to debug on linux, anyway). when I say that this error shown by superbonzo is not the cause of my problem, I say this cause I did make a simple test on Linux, out of my program's context, using this command and worked fine.. tks for the answer, hugs

  6. #6
    Join Date
    Jan 2006
    Location
    Belo Horizonte, Brazil
    Posts
    405

    Re: My software works on Windows, but not on Linux...

    Quote Originally Posted by superbonzo View Post
    I've not read all the code, but the line "while(!entrada.eof())" is wrong, causing a potential infinite loop; take a look here to see why.
    This is correct, but I don't think it's not the issue in the op's case. Since getline is being used inside the loop for a file stream it will eventually flag the EOF.

    Murilo, are you using the same file you created on Windows for Linux? The automatic conversions provided by the IOStream library are based on the native platform. So either you have to take care of the line endings explicitly or use a proper file.

  7. #7
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: My software works on Windows, but not on Linux...

    Quote Originally Posted by superbonzo View Post
    I've not read all the code, but the line "while(!entrada.eof())" is wrong, causing a potential infinite loop; take a look here to see why.
    The worst this error (and it *is* an error, IMO) usually does is to cause off-by-one behavior, nothing more. It may not even do that depending on the contents of the input file. For instance, if this is the input file (EOF isn't actually present, merely included for illustration):
    Code:
    1 2 3 4EOF
    then this will work fine:
    Code:
    ifstream in("file.txt");
    int val;
    while (!in.eof())
    {
        in >> val;
        cout << val << "\n";
    }
    But if we use this input file instead, the last value will be repeated twice in the output:
    Code:
    1 2 3 4      EOF
    Those look the same at first glance, but there's some whitespace at the end of the second file. Inputs different only by whitespace----observably different behavior. This is a bad thing, I'm sure you'll agree!

    The solution is to write the loop like this instead:
    Code:
    ifstream in("file.txt");
    int val;
    while (in >> val)
    {
        cout << val << "\n";
    }
    Last edited by Lindley; March 7th, 2011 at 04:20 PM.

  8. #8
    Join Date
    Nov 2010
    Posts
    11

    Re: My software works on Windows, but not on Linux...

    all opinions are valid, and I'll keep your suggestions in order to improve my code. anyway, the problem was simple. ltcmelo, yes, I was using the same file for windows and linux. what did I do? I wrote the files again, this time on linux ... and it worked perfectly

    Thanks to everyone who helped, you all are really good.

  9. #9
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: My software works on Windows, but not on Linux...

    Quote Originally Posted by Murilo Marchiori View Post
    all opinions are valid, and I'll keep your suggestions in order to improve my code. anyway, the problem was simple. ltcmelo, yes, I was using the same file for windows and linux. what did I do? I wrote the files again, this time on linux ... and it worked perfectly

    Thanks to everyone who helped, you all are really good.
    Most likely, then, you were encountering the fact that Windows and Linux use different end-of-line conventions. The extra \r characters were showing up as part of the line on Linux (when they would be discarded along with the \n on Windows), which was screwing up something somewhere.

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: My software works on Windows, but not on Linux...

    Quote Originally Posted by Murilo Marchiori View Post
    yes, I was using the same file for windows and linux. what did I do? I wrote the files again, this time on linux ... and it worked perfectly
    I see, I am using the debugger, and making manual tests here, but it don't show any error.
    If you used the debugger as you claimed you did, then this should have been obvious. If you inspected what you read in, you would have seen that what you read in was not correct.

    Regards,

    Paul McKenzie

  11. #11
    Join Date
    Nov 2010
    Posts
    11

    Re: My software works on Windows, but not on Linux...

    Quote Originally Posted by Paul McKenzie View Post
    If you used the debugger as you claimed you did, then this should have been obvious. If you inspected what you read in, you would have seen that what you read in was not correct.

    Regards,

    Paul McKenzie
    if you remember, I said I used the debugger in windows (visual c + +), and also said that I did not use the debugger on Linux, because I do not know. This is due to the fact that I was using gedit and did not know how to use the debugger in this case. like I said, the debugger showed no errors. Of course, the logic was right. my fault. I mistakenly thought the debugger show me only logical errors, and how the visual debugger showed no errors, I stopped worrying about it and went looking for the error by manual tests. if I had used the debugger in linux I would see the error in reading the files... beginner :P
    I will research how to use the debugger in this case.

    anyway, thanks for the comment.

  12. #12
    Join Date
    Apr 1999
    Posts
    27,449

    Re: My software works on Windows, but not on Linux...

    Quote Originally Posted by Murilo Marchiori View Post
    if you remember, I said I used the debugger in windows (visual c + +), and also said that I did not use the debugger on Linux, because I do not know.
    Before you write one line of C++ code on a new system, always determine if and how you can use the debugger for that system. Then you write a "Hello World" program to familiarize yourself with the tools (compiler, linker, debugger, etc.)

    Otherwise, you will be developing with one hand tied behind your back, and sooner or later, you'll give up if there is no debugger available due to an error occurring in a non-trivial program.

    Regards,

    Paul McKenzie

  13. #13
    Join Date
    Oct 2008
    Posts
    1,456

    Re: My software works on Windows, but not on Linux...

    Quote Originally Posted by Lindley View Post
    The worst this error (and it *is* an error, IMO) usually does is to cause off-by-one behavior, nothing more ...
    then this will work fine:
    given that file content, yes, it works as expected; but what happens if "in >> val" fails ? you'll have an infinite loop. So the worst case is an infinite loop, isn't it ?

  14. #14
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: My software works on Windows, but not on Linux...

    That's true for that toy example. Another nice aspect of the corrected approach is that it will fail in a nicer way given bad input.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured