web-dev-qa-db-fra.com

Fractionnement de chaînes C ++ sur plusieurs lignes (syntaxe de code, pas d'analyse)

À ne pas confondre avec la façon de diviser une chaîne en analyse syntaxique, par exemple:
Fractionner une chaîne en C++?

Je suis un peu confus quant à la façon de diviser une chaîne en plusieurs lignes en c ++.

Cela ressemble à une question simple, mais prenez l'exemple suivant:

#include <iostream>
#include <string>
main() {
  //Gives error
  std::string my_val ="Hello world, this is an overly long string to have" +
    " on just one line";
  std::cout << "My Val is : " << my_val << std::endl;

  //Gives error
  std::string my_val ="Hello world, this is an overly long string to have" &
    " on just one line";  
  std::cout << "My Val is : " << my_val << std::endl;
}

Je me rends compte que je pourrais utiliser la méthode std::stringappend(), mais je me demandais s'il y en avait des plus courtes/plus élégantes (par exemple plus de type python, bien que les guillemets triples etc. ne soient pas supportés dans c ++) façon de casser des chaînes en c ++ sur plusieurs lignes pour plus de lisibilité.

Un endroit où cela serait particulièrement souhaitable est lorsque vous passez des littéraux de chaîne longue à une fonction (par exemple une phrase).

63
Jason R. Mick

Ne mettez rien entre les cordes. Une partie de l'étape de lexage C++ consiste à combiner des littéraux de chaîne adjacents (même sur des sauts de ligne et des commentaires) en un seul littéral.

#include <iostream>
#include <string>
main() {
  std::string my_val ="Hello world, this is an overly long string to have" 
    " on just one line";
  std::cout << "My Val is : " << my_val << std::endl;
}

Notez que si vous voulez une nouvelle ligne dans le littéral, vous devrez l'ajouter vous-même:

#include <iostream>
#include <string>
main() {
  std::string my_val ="This string gets displayed over\n" 
    "two lines when sent to cout.";
  std::cout << "My Val is : " << my_val << std::endl;
}

Si vous souhaitez mélanger un #defined constante entière dans le littéral, vous devrez utiliser des macros:

#include <iostream>
using namespace std;

#define TWO 2
#define XSTRINGIFY(s) #s
#define STRINGIFY(s) XSTRINGIFY(s)

int main(int argc, char* argv[])
{
    std::cout << "abc"   // Outputs "abc2DEF"
        STRINGIFY(TWO)
        "DEF" << endl;
    std::cout << "abc"   // Outputs "abcTWODEF"
        XSTRINGIFY(TWO) 
        "DEF" << endl;
}

Il y a une certaine bizarrerie à cause de la façon dont l'opérateur du processeur stringify fonctionne, donc vous avez besoin de deux niveaux de macro pour obtenir la valeur réelle de TWO pour en faire un littéral de chaîne.

103
Eclipse

Sont-ils tous les deux des littéraux? La séparation de deux littéraux de chaîne avec des espaces est identique à la concaténation: "abc" "123" est le même que "abc123". Cela s'applique aussi bien au C droit qu'au C++.

9
mkb

Je ne sais pas si c'est une extension dans GCC ou si c'est standard, mais il semble que vous pouvez continuer un littéral de chaîne en terminant la ligne avec une barre oblique inverse (tout comme la plupart des types de lignes peuvent être étendus dans ce manoir en C++, par exemple une macro couvrant plusieurs lignes).

#include <iostream>
#include <string>

int main ()
{
    std::string str = "hello world\
    this seems to work";

    std::cout << str;
    return 0;
}
4
rmeador