2013-08-22 3 views
2

Je souhaite utiliser la fonction gets() pour std::string str. Mais je reçois une erreur:utilise std :: string comme tableau de caractères

invalid conversion from 'const char*' to 'char*'

La fonction strlen() d'autre part ne donne aucune erreur lorsque j'écris

int len = strlen(str.c_str()) 

mais gets(NUM.c_str()) donne l'erreur.

Des suggestions? Je dois utiliser std::string et gets() car la taille de mon personnage est inconnue.

+0

Un mot: "Ne pas utiliser' gets'. " –

+4

@KerrekSB C'est trois, sans doute quatre mots. – orlp

+0

Utilisez ['std :: getline'] (http://fr.cppreference.com/w/cpp/string/basic_string/getline) au lieu de – Praetorian

Répondre

9

c_str() renvoie un pointeur const au contenu de la chaîne, vous ne pouvez donc pas l'utiliser pour modifier la chaîne.

Même si vous avez fait contourner ce (que vous devriez vraiment pas), il serait impossible de changer la taille de la chaîne (comme vous essayez de le faire), puisque c'est géré par l'objet string. Le mieux que vous puissiez faire est d'écrire sur la mémoire qui peut ne pas appartenir au string, ce qui provoque des plantages ou autres comportements non définis.

Même si vous avez eu un choix approprié pour écrire, ne pas utiliser gets. Il n'y a aucun moyen de l'empêcher de déborder le tampon, si la ligne d'entrée est trop longue. Il a été dépréciée en C depuis au moins 1999.

Any suggestions?

std::getline(std::cin, NUM); 
0

I want to use gets() function

gets() est C. Lorsque possible, il est préférable en C++ propose

Essayez plutôt getline comme ceci: -

std::getline(std::cin, NUM); 

Et comme JROK mentionné dans les commentaires: -

Faire du monde un meilleur endroit - ne pas utiliser obtient

+1

N'utilisez pas 'gets' dans C non plus. C'est obsolète, pour des raisons goo. –

+0

Oui, je suis entièrement d'accord. Je n'utilise jamais ça aussi !!! :) –

+0

Merci !!! .... fait !!!! – Sucho

0

En plus des problèmes en essayant d'utiliser gets en premier lieu, vous ne pouvez pas l'utiliser sur un tampon renvoyé de c_str() comme le tampon est un . const char * (qui pointe vers la mémoire tampon de chaîne détenue par l'objet std::string Si vous insistez sur l'utilisation gets(), vous devez créer votre propre tampon à lire dans:

char buffer[1024] = {0}; // temporary buffer 
gets(buffer); // read from stdin into the buffer 
std::string s(buffer); // store the contents of the buffer in a std::string 

pour une explication et un exemple des raisons pour lesquelles vous shou ld ne jamais utiliser gets: http://www.gidnetwork.com/b-56.html

Une approche beaucoup mieux est de

std::string s; // the std::string you are using 
std::getline(std::cin, s); // read the line 
5

où commencer ...

(1) Tout d'abord, un gets attend char*, mais std::string::c_str() retours const char*. Le but de std::string::c_str() est simplement de fournir une représentation C-chaîne des données de chaîne - il n'est pas destiné à fournir un tampon inscriptible.La fonction gets a besoin d'un tampon de caractères en écriture.

(2) En second lieu, vous pouvez utiliser std::string comme un tampon de caractères en écriture en utilisant l'opérateur [], en disant: versions

std::string s(100); // create a buffer of size 100 
char* buf = &s[0]; 

Ceci est garanti pour fonctionner correctement dans 11 C de, mais dans les versions antérieures de C++, il n'est pas nécessairement garanti que std::string fournisse un tampon mémoire contigu. (Bien que, dans la pratique, il le fait presque toujours.) Pourtant, si vous voulez un tampon, il est préférable d'utiliser std::vector<char>.

(3) Enfin, n'utilisez pas gets, JAMAIS. C'est ridiculement dangereux et rend votre programme vulnérable aux débordements de buffer et aux attaques par injection de shellcode. Le problème est que gets n'inclut pas un paramètre size, donc en pratique le programme lira toute quantité arbitraire d'octets dans le tampon, potentiellement débordant le tampon et résultant en un comportement indéfini. Cela a été historiquement un vecteur d'attaque pour de nombreux pirates, especially when gets is used with a stack array. La fonction fgets doit être utilisée à la place en C, car elle vous permet de spécifier un paramètre de taille de lecture maximale. En C++, il est préférable d'utiliser std::getline, car cela fonctionne directement avec un objet std::string et donc vous n'avez pas besoin de vous soucier de la taille du tampon.

Questions connexes