Duda sobre el control de la longitud de una cadena de caracteres

Iniciado por seryioo, 16 Agosto 2015, 20:59 PM

0 Miembros y 1 Visitante están viendo este tema.

seryioo

Buenas a todos, tengo una duda.

Si tengo las dimensiones de una cadena de caracteres...

Código (cpp) [Seleccionar]

char cadena1[80]


... e introduzco por ejemplo en cadena1: "El pajaro vuela", el caracter nulo "\0" estaría inmediatamente después de vuela\0 o estaría en la posición 80 de cadena1 por haber definido su tamaño previamente?

PD: Es que en un ejericio me salen datos basura... no se qué estoy haciendo mal.
Os dejo el código. El main ya venía hecho.

Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

typedef char TCadena [];

// Funciones para modificar cadenas de caracteres ----------------------

unsigned longitud (const TCadena cad);

void copiar(TCadena destino, const unsigned dim, const TCadena origen,
                                                              bool& ok);
// Copia los caracteres de la cadena origen en la cadena destino de
// tamañoo dim. Devuelve false en ok si no tiene capacidad suficiente

void agregar_char(TCadena destino, const unsigned dim, const char c,
                                                           bool& ok);
// Agrega el carácter c al final de la cadena destino.
// Devuelve ok a false cuando no tiene capacidad suficiente

void encadenar(TCadena destino, const unsigned dim,
                                 const TCadena origen, bool& ok);
// Agrega todos los caracteres de la cadena origen al final de la cadena
// destino. Devuelve ok a false cuando no tiene capacidad suficiente


//- Programa de prueba -------------------------------------------------

int main(){
    setlocale(LC_ALL, "spanish");

    char cadena1[80], cadena2[80];
    char c;
    bool ok;

    cout << "Introducir una cadena:\n";
    cin >> ws;
    cin.getline(cadena1,79);

    cout << "Introducir un carácter: ";
    cin >> c;
    agregar_char(cadena1, 80, c, ok);
    if(ok){
      cout << "Al agregarle el carácter la cadena queda:\n";
      cout << cadena1 << endl;
    } else {
      cout << "No hay espacio para agregar un carácter\n";
    }

    copiar(cadena2, 80, cadena1, ok);
    if (ok){
          cout << "La cadena copiada es: \n";
          cout << cadena2 << endl;
    } else {
          cout << "No hay espacio para la copia" << endl;
    }

    cout << "Pegando las dos cadenas resulta: \n";
    encadenar(cadena2, 80, cadena1, ok);
    if (ok){
          cout << cadena2 << endl << endl;
    } else {
          cout << "No hay espacio para encadenar" << endl;
    }

    cout<<longitud(cadena2);
    return 0;
}

//- Definiciones de funciones ------------------------------------------

unsigned longitud (const TCadena cad){
    unsigned pos=0;
    while (cad[pos]!='\0') ++pos;
    return pos;
}


void copiar(TCadena destino, const unsigned dim, const TCadena origen, bool& ok){
    if(longitud(origen)<=dim){
        ok=true;
        unsigned i=0;
        while(origen[i]!='\0'){
            destino[i]=origen[i];
            ++i;
        }//end while
    }else ok=false;
}

void agregar_char(TCadena destino, const unsigned dim, const char c, bool& ok){
        if(longitud(destino)<dim){
            destino[longitud(destino)]=c;
             ok=true;
        }else ok=false;
}

void encadenar(TCadena destino, const unsigned dim, const TCadena origen, bool& ok){
    if(longitud(origen)>dim-longitud(destino)){
        unsigned i=longitud(destino)+1;
        unsigned pos=0;
        while(origen[pos]!='\0'){
            destino[i]=origen[pos];
            ++i;
        }//end while
        ok=true;
    }else ok=false;
}



Stakewinner00

El carácter \0 estaría despues del último char leído, no en la posición 80.

Los carácteres basura seguramente es porque en la función agregar_caracter machacas el '\0' en la línea destino[longitud(destino)]=c; Y por tanto si los siguientes bytes son basura y no son \0, los imprimira. La manera más fácil es añadir un '\0' despues de modificar la cadena.
Si tenías la cadena "Vuela\0" y añades el caracter 'D', lo que estas haciendo es reemplazar el \0 por la D y queda "VuelaD", lo que tendría que pasar es que añade la 'D' entre la 'a' y el '\0' para que quede "VuelaD\0"

Espero haber ayudado, saludos

seryioo

#2
Buenas, gracias por tu respuesta.

He arreglado eso que dices, pero sigo teniendo el mismo error:

Código (cpp) [Seleccionar]
void agregar_char(TCadena destino, const unsigned dim, const char c, bool& ok){
       if(longitud(destino)<dim){
           destino[longitud(destino)]=c;
            destino[longitud(destino)+1]='\0';
            ok=true;
       }else ok=false;
}


PD:

Lo he arreglado, me he dado cuenta que al añadir el caracter la longitud de destino aumenta, por lo que guardo la longitud inicial para usarla correctamente despues, donde añado \0

Código (cpp) [Seleccionar]
void agregar_char(TCadena destino, const unsigned dim, const char c, bool& ok){
       unsigned i=longitud(destino);
       if(longitud(destino)<dim){
           destino[i]=c;
            destino[i+1]='\0';
            ok=true;
       }else ok=false;
}



Sigue sin funcionarme la función "encadenar". A ver si consigo encontrar el error y corregirla.

Código (cpp) [Seleccionar]

void encadenar(TCadena destino, const unsigned dim, const TCadena origen, bool& ok){
    unsigned lor=longitud(origen);
    unsigned ldes=longitud(destino);
    if(lor+ldes<=dim){
        ok=true;
        unsigned i=0;
        while(origen[i]!='\0'){
            destino[ldes+i]=origen[i];
            ++i;
        }//end while
        destino[i]='\0';
    } ok=false;
}