Je fais une simulation de quelques modèles Ising (treillis avec 1 ou -1) et je ne veux pas utiliser de fichiers (ne pas entrer dans détails ici, je suppose: D). Donc, la chose est, j'utilise stringstreams pour formater le nom de fichier de données & de données pour ensuite les séparer avec bash. Montrez-vous un exemple de codestd :: stringstream ne nomme pas un type (Global)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
void print2bash(string file, string data);
int main(int argc, char *argv[]){
int i, j, n = atoi(argv[1]);
// I want to put this outside main() {
stringstream ssbash; ssbash.clear(); ssbash.str("");
stringstream ssfile; ssfile.clear(); ssfile.str("");
//}
// So I don't have to do ss.clear and ss.str("") every time before using them
ssfile << "this_" << n << "_is_the_filename.dat" << endl;
for(i = 0; i < n ; i++){
for(j = 0; j < n; j++)
ssbash << i*n+j << "\t";
ssbash << endl;
}
print2bash(ssfile.str(), ssbash.str());
return 0;
}
// print2bash(); prints string data; to string file;
// This will be used to separate data
// afterwards (i.e. ./Ising.o <arguments> | bash)
void print2bash(string file, string data){
stringstream ssbash; ssbash.clear(); ssbash.str(data);
stringstream output; output.clear(); output.str("");
string line;
output << "for((i=0;i<1;i++)) do "<< endl; // Buffer all to bash at once
while(getline(ssbash,line))
output << " echo \"" << line << "\";" << endl;
output << "done >> " << file; // Appending
cout << output.str() << endl;
ssbash.clear(); ssbash.str("");
return ;
}
Une sortie régulière de ce programme « sstreams.o » serait
~work/Ising$ ./sstreams.o 5
for((i=0;i<1;i++)) do
echo "0 1 2 3 4 ";
echo "5 6 7 8 9 ";
echo "10 11 12 13 14 ";
echo "15 16 17 18 19 ";
echo "20 21 22 23 24 ";
done >> this_5_is_the_filename.dat
Vous obtenez la bonne idée? De ce flux de réflexion, ce que j'écris est ./sstreams.o 10 | bash
donc on obtient des fichiers bien séparés. Mais le problème est:
Je deviens fatigué d'écrire ces lignes chaque fois que je veux utiliser print2bash()
stringstream ssbash; ssbash.clear(); ssbash.str("");
stringstream ssfile; ssfile.clear(); ssfile.str("");
À cause de cela, je veux mettre (oh l'ironie!) les ss
comme des variables globales (je ne sais pas si c'est ce genre d'affreux donc le compilateur ne me laisse pas le faire: je ne suis qu'un physicien). Donc, même si j'écris std::stringstream
pour les variables ss après les #include
s (et using namespace std
), je reçois toujours l'erreur
error: ‘ssbash’ does not name a type
error: ‘ssbash’ does not name a type
error: ‘ssfile’ does not name a type
error: ‘ssfile’ does not name a type
du compilateur. J'espère que vous pouvez m'aider.
EDIT: [RESOLU]
Le problème est que si je voulais déclarer une stringstream
de main()
il a échoué à cause des membres clear
& str
où hors contexte afin qu'ils ne peuvent pas être utilisé. En outre, cette utilisation était inutile car stringstream
s sont créés avec des contenus vides, comme @jpalecek et @umlaeute l'ont fait remarquer.
J'ai déclaré les stringstream
s sur principale et comprennent un clear()
+ str("")
sur print2bash()
pour donner le résultat souhaité:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
stringstream ssbash, ssfile;
void print2bash(string file, string data);
int main(int argc, char *argv[]){
int i, j, n = atoi(argv[1]), p, np = atoi(argv[2]);
vector< vector<int> > chain; chain.resize(n*n);
for(p = 0; p < np; p++){
ssfile << "chain_p="<< p << "_filename.dat" << endl;
for(i = 0; i < n ; i++){
for(j = 0; j < n; j++){
chain[p].push_back(i*n + j);
ssbash << i*n+j << "\t";
}
ssbash << endl;
}
print2bash(ssfile.str(), ssbash.str());
}
return 0;
}
void print2bash(string file, string data){
ssbash.str(data);
stringstream output;
string line;
output << "for((i=0;i<1;i++)) do "<< endl; // Buffer all to bash at once
while(getline(ssbash,line))
output << " echo \"" << line << "\";" << endl;
output << "done >> " << file; // Appending
cout << output.str() << endl;
ssfile.clear(); ssfile.str("");
ssbash.clear(); ssbash.str("");
return ;
}
une sortie régulière de ./sstreams.o
~/work/Ising$ ./sstreams.o 4 2
for((i=0;i<1;i++)) do
echo "0 1 2 3 ";
echo "4 5 6 7 ";
echo "8 9 10 11 ";
echo "12 13 14 15 ";
done >> chain_p=0_filename.dat
for((i=0;i<1;i++)) do
echo "0 1 2 3 ";
echo "4 5 6 7 ";
echo "8 9 10 11 ";
echo "12 13 14 15 ";
done >> chain_p=1_filename.dat
Merci pour tout
Ok, je Je ne comprends vraiment pas pourquoi vous faites cela si compliqué. les appels à "clear" et "str" juste après la construction n'ont aucun effet. –
Je ne comprends vraiment pas votre approche globale. Il semble que votre programme C++ génère un script qui fait presque la même chose que votre programme C++. Êtes-vous sûr que c'est le meilleur moyen? –
@ BjörnPollex: il est un physicien, vous devez comprendre cela. – jpalecek