C # tiene una función de sintaxis donde puede concatenar muchos tipos de datos en una sola línea.
string s = new String();
s += "Hello world, " + myInt + niceToSeeYouString;
s += someChar1 + interestingDecimal + someChar2;
¿Cuál sería el equivalente en C ++? Hasta donde puedo ver, tendrías que hacerlo todo en líneas separadas, ya que no admite múltiples cadenas / variables con el operador +. Esto está bien, pero no se ve tan bien.
string s;
s += "Hello world, " + "nice to see you, " + "or not.";
El código anterior produce un error.
c++
string
compiler-errors
concatenation
Nick Bolton
fuente
fuente
char *
punteros entre sí. Eso es lo que genera el error, porque sumar punteros no tiene sentido. Como se indica a continuación, convierta al menos el primer operando en unstd::string
, y no hay ningún error en absoluto.Respuestas:
Eche un vistazo a este artículo del Gurú de la semana de Herb Sutter: The String Formatters of Manor Farm
fuente
std::string s = static_cast<std::ostringstream&>(std::ostringstream().seekp(0) << "HelloWorld" << myInt << niceToSeeYouString).str();
std::stringstream ss; ss << "Hello, world, " << myInt << niceToSeeYouString; std::string s = ss.str();
es más o menos una líneaEn 5 años nadie ha mencionado
.append
?fuente
s.append("One"); s.append(" line");
s.append("One").append(" expression");
Quizás debería editar el original para usar el valor de retorno de esta manera?s
en una línea diferente en el código C # equivalente y en su código C ++ que no se compila. Su C ++ deseado es els += "Hello world, " + "nice to see you, " + "or not.";
que se puede escribirs.append("Hello world, ").append("nice to see you, ").append("or not.");
append
es que también funciona cuando las cadenas contienen caracteres NUL.Esos literales de matriz de caracteres no son C ++ std :: strings; debe convertirlos:
Para convertir ints (o cualquier otro tipo de transmisión) puede usar un impulso lexical_cast o proporcionar su propia función:
Ahora puedes decir cosas como:
fuente
string("Hello world")
se realizan a través deoperator+()
definido en la clasestring
. Si no hay ningúnstring
objeto en la expresión, la concatenación se convierte en una simple suma de punteros de caractereschar*
.Su código puede escribirse como 1 ,
... pero dudo que sea lo que estás buscando. En su caso, probablemente esté buscando transmisiones:
1 " se puede escribir como ": esto solo funciona para literales de cadena. La concatenación la realiza el compilador.
fuente
const char smthg[] = "smthg"
: / ¿Es un error?#define
usar su cadena para evitar esto, aunque esto trae sus propios problemas.Usando C ++ 14 literales definidos por el usuario y
std::to_string
el código se vuelve más fácil.Tenga en cuenta que los literales de cadena de concatenación se pueden hacer en tiempo de compilación. Solo quite el
+
.fuente
std::literals::string_literals
, no al concepto de UDL.Para ofrecer una solución que sea más de una línea:
concat
se puede implementar una función para reducir la solución "clásica" basada en cadenas a una sola declaración . Se basa en plantillas variadas y reenvío perfecto.Uso:
Implementación:
fuente
En C ++ 20 podrás hacer:
Hasta entonces, podría hacer lo mismo con la biblioteca {fmt} :
Descargo de responsabilidad : soy el autor de {fmt}.
fuente
impulso :: formato
o std :: stringstream
fuente
El problema real era que la concatenación de literales de cadena con
+
falla en C ++:En C ++ (también en C), concatena los literales de cadena simplemente colocándolos uno al lado del otro:
Esto tiene sentido, si genera código en macros:
... una macro simple que se puede usar así
( demostración en vivo ... )
o, si insiste en usar los
+
literales de cadena for (como ya ha sido sugerido por underscore_d ):Otra solución combina una cadena y una
const char*
para cada paso de concatenaciónfuente
sprintf
es una opción, pero también hay std :: stringstream que evita problemas con buffers de menor tamaño.fuente
Tendría que definir el operador + () para cada tipo de datos que desea concenatear a la cadena, sin embargo, dado que el operador << está definido para la mayoría de los tipos, debe usar std :: stringstream.
Maldición, venció por 50 segundos ...
fuente
std::string operator+(std::string s, int i){ return s+std::to_string(i); }
Si escribe el
+=
, se ve casi igual que C #fuente
Como otros dijeron, el principal problema con el código OP es que el operador
+
no concatenaconst char *
; funciona constd::string
, sin embargo.Aquí hay otra solución que usa lambdas C ++ 11
for_each
y permite proporcionar unaseparator
para separar las cadenas:Uso:
Parece escalar bien (linealmente), al menos después de una prueba rápida en mi computadora; Aquí hay una prueba rápida que he escrito:
Resultados (milisegundos):
fuente
Tal vez te guste mi solución "Streamer" para hacerlo realmente en una línea:
fuente
Aquí está la solución de una línea:
Aunque es un poco feo, creo que es lo más limpio que puedes tener en C ++.
Estamos lanzando el primer argumento a a
std::string
y luego usando el orden de evaluación (de izquierda a derecha) deoperator+
para asegurarnos de que su operando izquierdo sea siempre astd::string
. De esta manera, concatenamos elstd::string
de la izquierda con elconst char *
operando a la derecha y devolvemos otrostd::string
, conectando en cascada el efecto.Nota: hay algunas opciones para el operando derecho, incluyendo
const char *
,std::string
ychar
.Depende de usted decidir si el número mágico es 13 o 6227020800.
fuente
Puede usar este encabezado para este respecto: https://github.com/theypsilon/concat
Debajo del capó usarás un std :: ostringstream.
fuente
Si está dispuesto a utilizarlo
c++11
, puede utilizar literales de cadena definidos por el usuario y definir dos plantillas de función que sobrecarguen el operador más para unstd::string
objeto y cualquier otro objeto. El único inconveniente es no sobrecargar los operadores plus destd::string
, de lo contrario el compilador no sabe qué operador usar. Puede hacerlo utilizando la plantillastd::enable_if
detype_traits
. Después de eso, las cadenas se comportan como en Java o C #. Vea mi ejemplo de implementación para más detalles.Código principal
Archivo c_sharp_strings.hpp
Incluya este archivo de encabezado en todos los lugares donde desea tener estas cadenas.
fuente
Algo como esto me funciona
fuente
Basado en las soluciones anteriores, hice una clase var_string para mi proyecto para facilitar la vida. Ejemplos:
La clase misma:
¿Todavía te preguntas si habrá algo mejor en C ++?
fuente
En c11:
esto le permite crear llamadas a funciones como esta:
imprimirá: número de mensaje: 10
fuente
También puede "extender" la clase de cadena y elegir el operador que prefiera (<<, &, |, etc ...)
Aquí está el código que usa el operador << para mostrar que no hay conflicto con las transmisiones
nota: si descomenta s1.reserve (30), solo hay 3 solicitudes de operador nuevas () (1 para s1, 1 para s2, 1 para reserva; desafortunadamente no puede reservar en el momento del constructor); sin reserva, s1 tiene que solicitar más memoria a medida que crece, por lo que depende de su factor de crecimiento de implementación del compilador (el mío parece ser 1.5, 5 llamadas nuevas () en este ejemplo)
fuente
Stringstream con una simple macro de preprocesador que utiliza una función lambda parece agradable:
y entonces
fuente
Esto funciona para mi:
Salida:
fuente
const
(si se requiere cero almacenamiento)enum
sería una?¿Has tratado de evitar el + =? en su lugar use var = var + ... funcionó para mí.
fuente
#include <iostream.h> // string
#include <system.hpp> // ansiString