-
March 7th, 2011, 10:53 AM
#1
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;
}
-
March 7th, 2011, 11:04 AM
#2
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.
-
March 7th, 2011, 01:15 PM
#3
Re: My software works on Windows, but not on Linux...
Originally Posted by superbonzo
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...
-
March 7th, 2011, 01:49 PM
#4
Re: My software works on Windows, but not on Linux...
Originally Posted by Murilo Marchiori
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
-
March 7th, 2011, 03:08 PM
#5
Re: My software works on Windows, but not on Linux...
Originally Posted by Paul McKenzie
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
-
March 7th, 2011, 04:07 PM
#6
Re: My software works on Windows, but not on Linux...
Originally Posted by superbonzo
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.
-
March 7th, 2011, 04:18 PM
#7
Re: My software works on Windows, but not on Linux...
Originally Posted by superbonzo
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):
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:
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.
-
March 7th, 2011, 05:20 PM
#8
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.
-
March 7th, 2011, 05:37 PM
#9
Re: My software works on Windows, but not on Linux...
Originally Posted by Murilo Marchiori
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.
-
March 7th, 2011, 07:30 PM
#10
Re: My software works on Windows, but not on Linux...
Originally Posted by Murilo Marchiori
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
-
March 7th, 2011, 08:27 PM
#11
Re: My software works on Windows, but not on Linux...
Originally Posted by Paul McKenzie
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.
-
March 7th, 2011, 11:18 PM
#12
Re: My software works on Windows, but not on Linux...
Originally Posted by Murilo Marchiori
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
-
March 8th, 2011, 03:27 AM
#13
Re: My software works on Windows, but not on Linux...
Originally Posted by Lindley
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 ?
-
March 8th, 2011, 10:29 AM
#14
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|