Taille maxi d'un char en C++
Résolu/Fermé
ptit81
Messages postés
29
Date d'inscription
mercredi 12 septembre 2007
Statut
Membre
Dernière intervention
6 décembre 2012
-
16 juil. 2009 à 17:04
mamiemando Messages postés 33475 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 janvier 2025 - 24 juil. 2009 à 10:10
mamiemando Messages postés 33475 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 janvier 2025 - 24 juil. 2009 à 10:10
A voir également:
- Taille maxi d'un char en C++
- Comment réduire la taille d'un fichier - Guide
- Reduire taille photo - Guide
- Afficher taille dossier windows - Guide
- Règle cm taille réelle en ligne - Guide
- Taille iphone 14 - Guide
8 réponses
mamiemando
Messages postés
33475
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
22 janvier 2025
7 815
16 juil. 2009 à 19:17
16 juil. 2009 à 19:17
Première chose pour t'expliquer pourquoi 1000 ou 10000 ne changent rien :
Ici tu alloues un bloc de 1000 char et tu stockes l'adresse de ce bloc dans c_equation_cc1 (type char *). Ensuite tu réaffectes cette adresse avec celle de la chaîne "X1_i_dot=W1_i_i*X1_i". La zone pointée par c_equation_cc1 n'est donc plus un bloc de 1000 char, mais un bloc d'une vingtaine de char d'où le problème.
Si tu programmes en C++ (cf le titre) autant utiliser les fonctionnalités du C++ et n'utiliser les fonctions que C qu'en cas de nécessité. On peut avoir un code qui s'affranchit complètement des notions de dimensionnement de buffer, par exemple en utilisant la classe std::ostringstream :
Petites précisions :
1) Un std::ostringstream peut être vu comme un flux sur un buffer de taille virtuellement infinie (comprendre on ne se pose pas de question en terme d'allocation mémoire). L'opérateur << permet de rajouter des choses à la fin du flux. La constante std::endl désigne le retour à la ligne (\n) en C++.
2) Note qu'ici on ne manipule pas que des std::string et des char* d'où l'utilité des std::ostringstream, sinon on aurait pu se contenter d'utiliser des std::string. Il n'est pas très judicieux de faire itoa la ou un sprintf en C et un std::ostringstream en C++ s'avèrent plus pertinents.
3) Pour plus d'informations sur les classes std::string et std::ostringstream :
https://community.hpe.com/t5/custom/page/page-id/HPPSocialUserSignonPage?redirectreason=permissiondenied&referer=https%3A%2F%2Fcommunity.hpe.com%2Ft5%2FServers-Systems-The-Right%2FSGI-com-Tech-Archive-Resources-now-retired%2Fba-p%2F6992583
http://www.cplusplus.com/reference/sstream/ostringstream/ostringstream/
Bonne chance
char c_equation_cc1[1000]="X1_i_dot=W1_i_i*X1_i";
Ici tu alloues un bloc de 1000 char et tu stockes l'adresse de ce bloc dans c_equation_cc1 (type char *). Ensuite tu réaffectes cette adresse avec celle de la chaîne "X1_i_dot=W1_i_i*X1_i". La zone pointée par c_equation_cc1 n'est donc plus un bloc de 1000 char, mais un bloc d'une vingtaine de char d'où le problème.
Si tu programmes en C++ (cf le titre) autant utiliser les fonctionnalités du C++ et n'utiliser les fonctions que C qu'en cas de nécessité. On peut avoir un code qui s'affranchit complètement des notions de dimensionnement de buffer, par exemple en utilisant la classe std::ostringstream :
// Au début de ton fichier #include <string> #include <sstream> // A la déclaration de f_cc1 // Au lieu d'utiliser un char * autant utiliser une std::string std::string f_cc1; // Dans ta fonction std::ostringstream oss; oss << "X1_i_dot=W1_i_i*X1_i"; for(unsigned i = 1; i <= i_s; ++i){ oss << "+E1_i_" << i << "*U_" << i; } oss << ';' << std::endl << '}' << std::endl << std::endl; // Concatène le contenu de c_equation_cc1 à f_cc1 f_cc1 += c_equation_cc1.str();
Petites précisions :
1) Un std::ostringstream peut être vu comme un flux sur un buffer de taille virtuellement infinie (comprendre on ne se pose pas de question en terme d'allocation mémoire). L'opérateur << permet de rajouter des choses à la fin du flux. La constante std::endl désigne le retour à la ligne (\n) en C++.
2) Note qu'ici on ne manipule pas que des std::string et des char* d'où l'utilité des std::ostringstream, sinon on aurait pu se contenter d'utiliser des std::string. Il n'est pas très judicieux de faire itoa la ou un sprintf en C et un std::ostringstream en C++ s'avèrent plus pertinents.
3) Pour plus d'informations sur les classes std::string et std::ostringstream :
https://community.hpe.com/t5/custom/page/page-id/HPPSocialUserSignonPage?redirectreason=permissiondenied&referer=https%3A%2F%2Fcommunity.hpe.com%2Ft5%2FServers-Systems-The-Right%2FSGI-com-Tech-Archive-Resources-now-retired%2Fba-p%2F6992583
http://www.cplusplus.com/reference/sstream/ostringstream/ostringstream/
Bonne chance
ptit81
Messages postés
29
Date d'inscription
mercredi 12 septembre 2007
Statut
Membre
Dernière intervention
6 décembre 2012
2
17 juil. 2009 à 10:50
17 juil. 2009 à 10:50
Merci beaucoup.
C'est en effet plus simple que ce que je faisais.
Je pense qu'il y a quand même une coquille dans ce que tu as écris vu que tu crée oss mais tu ne l'utilise pas par la suite.
J'ai donc réécris avec mes notations:
std::string s_equation_cc1;
std::ostringstream oss;
oss << "X1_i_dot=W1_i_i*X1_i";
for(unsigned i = 1; i <= i_s; ++i)
{
oss << "+E1_i_" << i << "*U_" << i;
}
oss << ';' << std::endl << '}' << std::endl << std::endl;
s_equation_cc1 += oss.str();
Par contre, c'est vraiment bête mais après, j'arrive pas à imprimer dans un fichier (f_cc1, créé plus haut dans le code) le string "s_equation_cc1".
je fais:
fprintf(f_cc1,"%s",s_equation_cc1);
et après compilation (qui a l'air de bien se passer); ça m'ouvre une fenêtre windows où il est marqué:
"generation_modele_etat_pt.exe a rencontré un problème et doit fermer. Nous vous prions de nous excuser pour le désagrément encouru." etc.
et j'ai un warning:
" [Warning] cannot pass objects of non-POD type `struct std::string' through `...'; call will abort at runtime "
Pourtant, pour imprimer un string, c'est bien %s qu'il faut utiliser! non!
Merci d'avance...
C'est en effet plus simple que ce que je faisais.
Je pense qu'il y a quand même une coquille dans ce que tu as écris vu que tu crée oss mais tu ne l'utilise pas par la suite.
J'ai donc réécris avec mes notations:
std::string s_equation_cc1;
std::ostringstream oss;
oss << "X1_i_dot=W1_i_i*X1_i";
for(unsigned i = 1; i <= i_s; ++i)
{
oss << "+E1_i_" << i << "*U_" << i;
}
oss << ';' << std::endl << '}' << std::endl << std::endl;
s_equation_cc1 += oss.str();
Par contre, c'est vraiment bête mais après, j'arrive pas à imprimer dans un fichier (f_cc1, créé plus haut dans le code) le string "s_equation_cc1".
je fais:
fprintf(f_cc1,"%s",s_equation_cc1);
et après compilation (qui a l'air de bien se passer); ça m'ouvre une fenêtre windows où il est marqué:
"generation_modele_etat_pt.exe a rencontré un problème et doit fermer. Nous vous prions de nous excuser pour le désagrément encouru." etc.
et j'ai un warning:
" [Warning] cannot pass objects of non-POD type `struct std::string' through `...'; call will abort at runtime "
Pourtant, pour imprimer un string, c'est bien %s qu'il faut utiliser! non!
Merci d'avance...
mamiemando
Messages postés
33475
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
22 janvier 2025
7 815
17 juil. 2009 à 11:09
17 juil. 2009 à 11:09
Je pense qu'il y a quand même une coquille dans ce que tu as écris vu que tu crée oss mais tu ne l'utilise pas par la suite.
Ben si j'utilisais oss (avec les opérateur <<, oss.str() pour écrire dans la chaîne etc...).
Par contre, c'est vraiment bête mais après, j'arrive pas à imprimer dans un fichier (f_cc1, créé plus haut dans le code) le string "s_equation_cc1".
je fais: fprintf(f_cc1,"%s",s_equation_cc1);
C'est normal un std::string n'est pas un char *, pour extraire le char * correspondant tu dois utiliser la méthode c_str(). Regarde les liens que je t'ai donné sur les objets std::string et std::ostringstream.
De plus pour manipuler un fichier il serait plus judicieux d'utiliser la classe std::ofstream qui s'utilise ensuite comme un std::ostringstream. Avec un peu de chance tu n'as même pas besoin de faire une étape par un std::ostringstream et tu peux écrire directement dans le fichier.
Bonne chance
Ben si j'utilisais oss (avec les opérateur <<, oss.str() pour écrire dans la chaîne etc...).
Par contre, c'est vraiment bête mais après, j'arrive pas à imprimer dans un fichier (f_cc1, créé plus haut dans le code) le string "s_equation_cc1".
je fais: fprintf(f_cc1,"%s",s_equation_cc1);
C'est normal un std::string n'est pas un char *, pour extraire le char * correspondant tu dois utiliser la méthode c_str(). Regarde les liens que je t'ai donné sur les objets std::string et std::ostringstream.
De plus pour manipuler un fichier il serait plus judicieux d'utiliser la classe std::ofstream qui s'utilise ensuite comme un std::ostringstream. Avec un peu de chance tu n'as même pas besoin de faire une étape par un std::ostringstream et tu peux écrire directement dans le fichier.
#include <fstream> #include <iostream> int main(){ const char *filename = "pouet.txt"; std::ofstream ofs(filename); if(!ofs){ std::cerr << "can't write " << filename << std::endl; return 1; } ofs << "plop" << 1.23 << std::endl; ofs.close(); return 0; }
Bonne chance
ptit81
Messages postés
29
Date d'inscription
mercredi 12 septembre 2007
Statut
Membre
Dernière intervention
6 décembre 2012
2
21 juil. 2009 à 13:06
21 juil. 2009 à 13:06
La première méthode proposée ne marche pas parce qu'avec c_str, il me tronque mon string au bout d'un certain nombre de caractère et je retombe sur le problème précédent.
Pour la deuxième méthode, j'ai pas trouvé comment utiliser le ofstream sur un fichier déjà commencé.
Quand je l'utilise, il a l'air de me remettre systématiquement le fichier à blanc et si je ne veux pas recommencer entièrement mon code, il faudrait que je puisse continuer un fichier existant. (comme on peut le faire dans les options du fprintf).
A part ça, c'est vraiment une bonne idée car ça a l'air, encore une fois, de simplifier beaucoup l'écriture.
Est ce que quelqu'un a une idée?
merci d'avance
Pour la deuxième méthode, j'ai pas trouvé comment utiliser le ofstream sur un fichier déjà commencé.
Quand je l'utilise, il a l'air de me remettre systématiquement le fichier à blanc et si je ne veux pas recommencer entièrement mon code, il faudrait que je puisse continuer un fichier existant. (comme on peut le faire dans les options du fprintf).
A part ça, c'est vraiment une bonne idée car ça a l'air, encore une fois, de simplifier beaucoup l'écriture.
Est ce que quelqu'un a une idée?
merci d'avance
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
mamiemando
Messages postés
33475
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
22 janvier 2025
7 815
21 juil. 2009 à 14:22
21 juil. 2009 à 14:22
La première méthode proposée ne marche pas parce qu'avec c_str, il me tronque mon string au bout d'un certain nombre de caractère et je retombe sur le problème précédent.
Peux-tu nous donner le code complet ? Normalement il n'y a pas de raison que ta chaîne soit tronquée, je pense que tu as dû faire une erreur quelque part.
Pour la deuxième méthode, j'ai pas trouvé comment utiliser le ofstream sur un fichier déjà commencé.
Il faut passer à la méthode open des flags supplémentaires pour écrire en mode "append".
http://www.cplusplus.com/reference/fstream/ofstream/open/
Je verrais bien un truc du genre :
Quand je l'utilise, il a l'air de me remettre systématiquement le fichier à blanc et si je ne veux pas recommencer entièrement mon code, il faudrait que je puisse continuer un fichier existant. (comme on peut le faire dans les options du fprintf).
Oui c'est normal. Par défaut un ofstream se comporte comme un fopen(fp,"pouet.txt","w");
A part ça, c'est vraiment une bonne idée car ça a l'air, encore une fois, de simplifier beaucoup l'écriture.
Ca ça ne fait aucun doute ^^ Le C++ simplifie grandement les questions existentielles du genre "comment je dimensionne mon buffer" et la gestion de la mémoire en général. De plus les entrées/sorties sont souvent plus pratiques en C++ qu'en C.
Bonne chance
Peux-tu nous donner le code complet ? Normalement il n'y a pas de raison que ta chaîne soit tronquée, je pense que tu as dû faire une erreur quelque part.
Pour la deuxième méthode, j'ai pas trouvé comment utiliser le ofstream sur un fichier déjà commencé.
Il faut passer à la méthode open des flags supplémentaires pour écrire en mode "append".
http://www.cplusplus.com/reference/fstream/ofstream/open/
Je verrais bien un truc du genre :
std::ofstream ofs.open("pouet.txt",std::app);
Quand je l'utilise, il a l'air de me remettre systématiquement le fichier à blanc et si je ne veux pas recommencer entièrement mon code, il faudrait que je puisse continuer un fichier existant. (comme on peut le faire dans les options du fprintf).
Oui c'est normal. Par défaut un ofstream se comporte comme un fopen(fp,"pouet.txt","w");
A part ça, c'est vraiment une bonne idée car ça a l'air, encore une fois, de simplifier beaucoup l'écriture.
Ca ça ne fait aucun doute ^^ Le C++ simplifie grandement les questions existentielles du genre "comment je dimensionne mon buffer" et la gestion de la mémoire en général. De plus les entrées/sorties sont souvent plus pratiques en C++ qu'en C.
Bonne chance
ptit81
Messages postés
29
Date d'inscription
mercredi 12 septembre 2007
Statut
Membre
Dernière intervention
6 décembre 2012
2
21 juil. 2009 à 14:37
21 juil. 2009 à 14:37
Voici mon bout de code:
std::ostringstream oss_e_cc1;
oss_e_cc1 << "X1_i_dot=W1_i_i*X1_i";
for(unsigned i = 1; i <= i_s; i++)
{
oss_e_cc1 << "+E1_i_" << i << "*U_" << i;
}
std::string s_equation_cc1;
s_equation_cc1 += oss_e_cc1.str();
fprintf(f_cc1," %s%s",s_equation_cc1.c_str(),";\n}\n\n");
Je regarde ce que ça donne d'utiliser std::app
std::ostringstream oss_e_cc1;
oss_e_cc1 << "X1_i_dot=W1_i_i*X1_i";
for(unsigned i = 1; i <= i_s; i++)
{
oss_e_cc1 << "+E1_i_" << i << "*U_" << i;
}
std::string s_equation_cc1;
s_equation_cc1 += oss_e_cc1.str();
fprintf(f_cc1," %s%s",s_equation_cc1.c_str(),";\n}\n\n");
Je regarde ce que ça donne d'utiliser std::app
ptit81
Messages postés
29
Date d'inscription
mercredi 12 septembre 2007
Statut
Membre
Dernière intervention
6 décembre 2012
2
24 juil. 2009 à 08:19
24 juil. 2009 à 08:19
Pour finir, j'ai recodé entièrement en C++ et ça marche très bien en utilisant ostringstream et ofstream.
mamiemando
Messages postés
33475
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
22 janvier 2025
7 815
24 juil. 2009 à 10:10
24 juil. 2009 à 10:10
Parfait ! Bonne continuation !