Handling text strings in C++

For c++

  1. How do I add a "newline" or enter + the value of a numeric variable to a text string?
  2. How can I get that numeric value from the last line of a text string?
 6
Author: Miquel Coll, 2016-07-13

2 answers

How do I add a "newline" or enter ?

The newline is a character type known as a" non-printable character " because it affects how the text is displayed but has no graphical representation.

The ASCII character table contains the list of printable and non-printable characters:

ASCII was first published as standard in 1967 and was last updated in 1986. currently defines codes for 32 non-printing characters, of which most are control characters have an effect on how text is rendered, the more other 95 printable characters that follow them in the numbering (starting with the space character).

Most of the time it is not possible to write non-printable characters in the code, not only because it has no graphical representation but because they can cause compilation problems; the most clear is the new line:

std::string texto = "La lluvia en Sevilla
es una maravilla.";

The above example causes error because the compiler considers both lines as separate instructions because the new line is in the middle of the text. To avoid this problem most programming languages use escape sequences.

Escape sequences.

An escape sequence is usually written with a downbar (\) followed by a default code for said character.

Some of the escape sequences accepted in C++ are as follows :

We see that the new line has the escape sequence \n, which in C++ would be used as follows:

std::cout << "La lluvia en Sevilla\nes una maravilla.";
//                                ^^

And the text would be displayed as follows:

La lluvia en Sevilla
es una maravilla.

Raw text Literal (C++11 or higher).

In C++ as of the 2011 Standard It is possible to use an alternative to escape sequences to include some non-printable characters in a text string, the alternative is to use raw text literals ( Raw string literals ).

A raw text literal opens with the sequence R"( and closes with the sequence )"1 so this text:

std::cout << R"(La lluvia en Sevilla
es una maravilla.)";

Displays correctly:

La lluvia en Sevilla
es una maravilla.

Keep in mind that the raw text literal is not suitable for all control characters, for example: there is no way to write the Beep character in the code. It should also be mentioned that in a normal text literal the sequence "\n" produces a new line while in a raw text literal the sequence "\n" produces the descending diagonal character \ and the letter Jan n.

The value of a numeric variable to a text string.

To display variable values, you can use the header <iostream> of which the object std::cout forms part.

The <iostream> header handles user communication with the console and you can use it as follows:

#include <iostream>

int main()
{
    std::cout << "La lluvia en Sevilla\nes una maravilla.";
    float PI = 3.14;
    int entero = 10;
    short corto = 9;
    unsigned long long fabada = 0xfabada;

    std::cout << "Pi no es tres: " << PI      << '\n'
              << "El entero es: "  << entero  << '\n'
              << "El corto es: "   << corto   << '\n'
              << "El valor de la fabada es: " << fabada;

    return 0;
}

As you can see, to display a variable, you can inject it using the operator<<. In the example above, text and variables are injected into the std::cout object which is known as "console output", if you want to add the variable in a text string, you will need the headers <string> and <sstream>:

  • the <string> header allows you to handle and store text strings.
  • the <sstream> header allows you to format text to data.

You can use them like this:

#include <iostream>
#include <string>
#include <sstream>

int main()
{
    std::string cadena("Este es el texto inicial\n");
    std::stringstream s;
    s << cadena << "añadimos la fabada " << fabada << "\n\tEsto esta tabulado!";
    std::cout << s.str();

    return 0;
}

The above code should display the following text:

 Este es el texto inicial
 añadimos la fabada 16431834
         Esto esta tabulado!

As in the previous case, we have used the operator << to inject into the object s various data, the object s (of type std::stringstream) has them transformed into text. When we needed to retrieve that data, we simply called the function str() of the object s.

You can see the whole example in [Wandbox] , which is an online C++ compiler that you can experiment with.

How can I get that numeric value from the last line of a text string?

Move from text to number.

C++ has two libraries that can take care of passing text to number, the header <cstdlib> it is a C++ adaptation of a C library and contains the function std::atoi from the header <cstdlib>:

std::string cuarenta_y_dos("42");
int numero = std::atoi("42") + std::atoi(cuarenta_y_dos.c_str());

The function std::atoi expects to receive a pointer to a string, so the c_str method of std::string must be called.

But I prefer the option of using a text stream :

std::stringstream stream("42");
int numero = 0;
stream >> numero; // aqui inyectamos el valor 42 a la variable numero

Read the last line of a text.

I understand that the last line is that text that goes from the the last line break and the end of the text, so you can get that sub-string by doing a Reverse Search (from the end to the beginning) of the last newline character, using the headers <algorithm> e <iterator>:

char texto1[] = "Hexakosioihexekontahexafobia\n666";
std::string texto2 = "Triscaidecafobia\n13";

auto ultimo1 = std::find(std::rbegin(texto1), std::rend(texto1), '\n');
auto ultimo2 = std::find(std::rbegin(texto2), std::rend(texto2), '\n');

In the above example we have used inverse iterators (which move from end to beginning) to do a search on texts, after the calls to the search function the variables ultimo1 and ultimo2 they will contain the position in which the newline character is located, from that position back (because the iterator is inverse) we will have the number:

char texto1[] = "Hexakosioihexekontahexafobia\n666";
std::string texto2 = "Triscaidecafobia\n13";

auto r1 = std::find(std::rbegin(texto1), std::rend(texto1), '\n');
auto r2 = std::find(std::rbegin(texto2), std::rend(texto2), '\n');

std::cout << '"' << &*(r1 - 1) << '"' << '\n'; // Imprime "666"
std::cout << '"' << &*(r2 - 1) << '"' << '\n'; // Imprime "13"

.


1other opening / closing sequences are possible, as long as the opening and closing match, for example: R"***(Literal de texto en crudo)***" is equally valid.

 18
Author: PaperBirdMaster, 2017-01-23 12:40:39

Goes an example, with some comment in the code.

#include <string>
#include <sstream>
#include <iostream>


/* 1) ¿Cómo agrego un "nueva línea" o enter +
   el valor de una variable numérica a una
   cadena de texto?
*/
template<typename T>
std::string agregarNum(const std::string& s, T num)
{
    std::string str{s};
    str += "\n" + std::to_string(num);
    return str;
}

/* 2) ¿Cómo puedo obtener ese valor numérico
      de la última línea de una cadena de texto?
*/
template<typename T>
T obtenerUltimoNum(const std::string& str)
{
    size_t pos = str.find_last_of("\n");
    if(pos != str.npos) {
        std::string sub = str.substr(pos+1);
        std::stringstream ss(sub);
        T num;
        ss >> num;
        return num;
    }
    throw std::runtime_error("error: no hay un número al final de la cadena.");
    // o return T{}; al estilo de atoi()
    // y si esperás al C++17 std::optional.
}

int main()
{
    std::string cadena {"Hola mundo"};

    cadena = agregarNum(cadena, 4.5);

    std::cout << "cadena: " << cadena << '\n';

    double num = obtenerUltimoNum<double>(cadena);

    std::cout << "num: " << num << '\n';

}
 2
Author: , 2016-07-17 01:44:52