Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Tastiera gaming MSI GK600 TKL: switch hot-swap, display LCD e tre modalità wireless
Tastiera gaming MSI GK600 TKL: switch hot-swap, display LCD e tre modalità wireless
MSI FORGE GK600 TKL WIRELESS: switch lineari hot-swap, tripla connettività, display LCD e 5 strati di fonoassorbimento. Ottima in gaming, a 79,99 euro
DJI Osmo Pocket 4: la gimbal camera tascabile cresce e ha nuovi controlli fisici
DJI Osmo Pocket 4: la gimbal camera tascabile cresce e ha nuovi controlli fisici
DJI porta un importante aggiornamento alla sua linea di gimbal camera tascabili con Osmo Pocket 4: sensore CMOS da 1 pollice rinnovato, gamma dinamica a 14 stop, profilo colore D-Log a 10 bit, slow motion a 4K/240fps e 107 GB di archiviazione integrata. Un prodotto pensato per i creator avanzati, ma che convince anche per l'uso quotidiano
Sony INZONE H6 Air: il primo headset open-back di Sony per giocatori
Sony INZONE H6 Air: il primo headset open-back di Sony per giocatori
Il primo headset open-back della linea INZONE arriva a 200 euro con driver derivati dalle cuffie da studio MDR-MV1 e un peso record di soli 199 grammi
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 21-06-2013, 23:18   #1
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
[C++] Bug di GCC (o meglio, MinGW)?

Ciao,
ho questo codice:
Codice:
int main(int arcg, char* argv[])
{
	{
		// Open input file stream
		ifstream ifs("Test Element.txt");
		if (!ifs)
			throw runtime_error("Couldn't open the input file!");

		// Find the beginning of the Element Data section
		string line;
		while (getline(ifs, line, '\n'), line != "$* ELEMENT DATA")
		{	
			if (ifs.eof())
			{
				cout << "Cannot find Species Data!!" << endl;
				return 0;
			}
		}
	
		// Save the beginning of the Element Data section
		streampos begin = ifs.tellg();
	}
}
con questo file di testo:
Codice:
!File di prova per testare la routine di gestione degli elementi

$* ELEMENT DATA
C  .1201070000D+02 CO2          CO2          .3700000000D-03
H  .1007940000D+01 H2O          H2O          .0000000000D+00
N  .1400670000D+02 N2           N2           .7809000000D+00
O  .1599940000D+02 O2           O2           .2095000000D+00
$* END OF ELEMENT DATA
Ebbene, se eseguo il tutto in VS 2012, begin ha valore 85, mentre se uso QtCreator con MinGW (4.7, o 4.8, non cambia) ha valore 94, che è ERRATO!
Infatti se poi faccio ifs.seekg(begin) e uso getline, in VS ottengo la linea intera
Codice:
C  .1201070000D+02 CO2          CO2          .3700000000D-03
mentre con MinGW ottengo
Codice:
70000D+02 CO2          CO2          .3700000000D-03
e non capisco davvero perchè! Mi sfugge qualcosa o è un baco?
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 22-06-2013, 09:25   #2
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Avrei potuto svegliarmi prima a cercare in Google...speriamo almeno che possa tornare utile a qualcun'altro
http://stackoverflow.com/questions/9...x-about-file-r
Quote:
The difference you're seeing between Windows and Linux is because the file is open in text mode: newline characters will be converted silently by the implementation. This means that the combination "\r\n" (used in Windows for newlines) will be converted to a single '\n' character in Windows, making the file have only 8 characters. Note how vim shows a ^M at the end of the first line: that's the '\r' part. In Linux a newline is just '\n'.

You should open the file in binary mode if you want to preserve the original as is:
Codice:
file.open(path, std::ios_base::in | std::ios_base::binary);
Io sono su Windows, ma MinGW a quanto pare usa le stesse librerie di GCC per Linux e quindi il discorso si applica anche al mio caso
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 22-06-2013, 09:27   #3
nico159
Senior Member
 
Iscritto dal: Aug 2003
Città: Barletta (BA)
Messaggi: 939
Su Linux con GCC 4.8.1, il tuo file con codifica UNIX da il risultato giusto (82, C .1201070000D+02 CO2 CO2 .3700000000D-03)

Già il fatto che VS ti dica che ti trovi in posizione 85 è strano e fa pensare proprio che il file ha una codifica Windows (ovvero \r\n al posto di \n)

Ecco cosa succede se uso la codifica Windows sul file:
Cannot find Species Data!!
Che è il risultato atteso

VS funziona correttamente perchè la libreria standard di C++ MS controlla il fine riga come prima cosa anche se imposti un tuo delimitatore

Per MinGW invece mi pare un bug - certo che è strano che nessuno lo abbia notato prima - prova a chiedere nella loro mailing list

Forse la maniera più semplice, è usare la codifica *NIX

Fai sapere che ti rispondono sulla loro mailing list
__________________
In a world without fences, who needs Gates?
Power by: Fedora 8 - Mac OS X 10.4.11
nico159 è offline   Rispondi citando il messaggio o parte di esso
Old 22-06-2013, 09:46   #4
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Intanto grazie per la risposta!
Io sono stato un po' precipitoso a cantar vittoria: se apro il file in modalità binaria, ora ottengo ad un certo punto
line == "$* ELEMENT DATA\r"
e quel CR fa fallire la comparazione...
Intanto scrivo alla mailing list di MinGW, poi continuo a provare...il fatto strano è che seekg sembra funzionare bene, è proprio tellg che scazza...
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 22-06-2013, 11:15   #5
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Update: aprendo il file in modalità binaria, leggendo carattere per carattere e stampando i caratteri su un file di output, ottengo che 'C' è il carattere immediatamente successivo all'85 e '7' è successivo a 94:
Quote:
Character 80 = D
Character 81 = A
Character 82 = T
Character 83 = A
Character 84 = \r
Character 85 = \n
Character 86 = C
Character 87 =
Character 88 =
Character 89 = .
Character 90 = 1
Character 91 = 2
Character 92 = 0
Character 93 = 1
Character 94 = 0
Character 95 = 7
Character 96 = 0
Character 97 = 0
Character 98 = 0
Character 99 = 0
mentre aprendo il fine senza specificare ios_base::binary, 'C' sta dopo la posizione 82 come dicevi tu, nico:
Quote:
Character 80 = T
Character 81 = A
Character 82 = \n
Character 83 = C
Character 84 =
Character 85 =
Character 86 = .
Character 87 = 1
Character 88 = 2
Character 89 = 0
Character 90 = 1
Character 91 = 0
Character 92 = 7
Character 93 = 0
Character 94 = 0
Character 95 = 0
Character 96 = 0
Character 97 = D
Character 98 = +
Character 99 = 0
Sembrerebbe quindi che tellg() restituisca la posizione leggendo i caratteri "raw" anche se il file è stato aperto in modalità text...
Codice:
// Open input file stream
bool binary = true;
ifstream ifs;
if (binary)
	ifs.open("Test Element.txt", ios_base::binary);
else
	ifs.open("Test Element.txt");

if (!ifs)
	throw runtime_error("Couldn't open the input file!!\n");

ofstream ofs("tellg debug.txt");
if (!ofs)
	throw runtime_error("Couldn't open the output file!!\n");

char c;
string s;
int n = 0;
while (ifs.get(c))
{
	++n;
	s += c;

	if (n < 100)
	{
		ofs << "Character " << n << " = ";
		if (c == '\r')
			ofs << "\\r" << endl;
		else if (c == '\n')
			ofs << "\\n" << endl;
		else if (c == '\t')
			ofs << "\\t" << endl;
		else
			ofs << c << endl;
	}
}

cout << "String s: " << endl << s << endl << endl;

ofs << endl;
if (binary)
	ofs << "File opened in binary mode" << endl;
else
	ofs << "File opened in text mode" << endl;

ofs << "Character 82 = " << s[82] << endl << endl;
ofs << "Character 83 = " << s[83] << endl << endl;
ofs << "Character 85 = " << s[85] << endl << endl;
ofs << "Character 94 = " << s[94] << endl << endl;

return 0;
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 22-06-2013, 13:12   #6
nico159
Senior Member
 
Iscritto dal: Aug 2003
Città: Barletta (BA)
Messaggi: 939
Su *NIX (Linux, Mac OS X, FreeBSD...) non c'è alcun bisogno di conversione, quindi il discorso si chiude qua

La libreria standard di MS pare gestire i casi come std::getline direttamente all'interno della funzione, senza nascondere allo sviluppatore i caratteri \r che vengono conteggiati anche in text mode.
Non avendo mai programmato C++ su Windows non so dirti di più

MinGW nasconde le differenze tra \n e \r\n sfruttando il fatto che è qualcosa che lo standard prevede - il problema è che pare buggato

Il tutto non dovrebbe dare problemi, finchè:
- Non provi ad aprire un file creato su Windows su *NIX
- Non usi un compilatore che ha problemi

Più o meno è la situazione che si trova anche in altri luoghi (Java, C#...)
__________________
In a world without fences, who needs Gates?
Power by: Fedora 8 - Mac OS X 10.4.11
nico159 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Tastiera gaming MSI GK600 TKL: switch hot-swap, display LCD e tre modalità wireless Tastiera gaming MSI GK600 TKL: switch hot-swap, ...
DJI Osmo Pocket 4: la gimbal camera tascabile cresce e ha nuovi controlli fisici DJI Osmo Pocket 4: la gimbal camera tascabile cr...
Sony INZONE H6 Air: il primo headset open-back di Sony per giocatori Sony INZONE H6 Air: il primo headset open-back d...
Nutanix cambia pelle: dall’iperconvergenza alla piattaforma full stack per cloud ibrido e IA Nutanix cambia pelle: dall’iperconvergenza alla ...
Recensione Xiaomi Pad 8 Pro: potenza bruta e HyperOS 3 per sfidare la fascia alta Recensione Xiaomi Pad 8 Pro: potenza bruta e Hyp...
iPhone 18 Pro: il componente che garanti...
DeepL alza il livello: con Voice-to-Voic...
Apple sta utilizzando sempre più ...
Il MacBook Neo vende tanto? Microsoft le...
AST SpaceMobile BlueBird 7: Blue Origin ...
È il momento migliore per comprar...
Svendita MacBook Pro: c'è il mode...
Oggi questa TV TCL QLED da 43 pollici co...
Il caricatore multiplo da 200W che va be...
Top 7 Amazon, il meglio del meglio di qu...
Spento lo strumento LECP della sonda spa...
Voyager Technologies ha siglato un accor...
GoPro annuncia la linea MISSION 1 con tr...
Alcune varianti dei futuri Samsung Galax...
Il ridimensionamento di OnePlus in Europ...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 01:02.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v