Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - K-YreX

#381
Programación C/C++ / Re: ayuda rellenar ficheros C
27 Noviembre 2019, 14:14 PM
Bueno, te dejo aquí un ejemplo:

#define SIZE 100
int main(){
    char frase[SIZE];
    FILE *fichero = fopen("clientes.txt", "a"); // el segundo parametro = a -> agrega texto al final / = w -> borra lo que hay y agrega el nuevo texto
   
    printf("Introduce una frase: ");
    fgets(frase, SIZE, stdin); // las cadenas se guardan con fgets()

    fprintf(fichero, "%s", frase); // agrega una linea al final del fichero con la cadena guardada en frase

    fclose(fichero);
}

Además la función fgets() almacena también el ENTER de la entrada como un salto de línea al final de la cadena, por lo que cada frase se guardará en una línea diferente.
Cuando quieras evitar esto, puedes eliminar el salto de línea de la cadena así:

// Cabecera necesaria para utilizar la funcion strrchr()
#include <string.h>
//...
char *puntero = strrchr(frase, '\0'); // puntero que apunta al '\0' de la frase. El '\0' es siempre el ultimo caracter de una cadena en C
--puntero; // nos movemos una posicion a la izquierda para apuntar al salto de linea '\n' que esta justo antes del '\0'
*puntero = '\0'; // modificamos el '\n' por '\0' para indicar que la cadena termina ahi


Si por el contrario quieres guardar un dato en cada línea de un fichero y el valor no tiene el salto de línea implícito:

int main(){
    int edad;
    FILE *fichero = fopen("edades.txt", "a");

    printf("Introduce tu edad: ");
    scanf("%d", &edad);

    fprintf(fichero, "%d\n", edad); // Se agrega el salto de linea ahi

    fclose(fichero);
}
#382
Programación C/C++ / Re: cadenas y uso de MAYUSCULA
26 Noviembre 2019, 19:42 PM
Cita de: CalgaryCorpus en 26 Noviembre 2019, 15:11 PM
Buscar el ultimo espacio en blanco podria fallar si la frase tiene solo 1 palabra, sin espacio alguno.

Tal vez resulte mejor poner un puntero al final y devolverse hasta llegar o al inicio de la palabra o bien a un espacio en blanco.
Cierto, se podría arreglar así:

char *puntero = strrchr(frase, ' ');
if(puntero == NULL)
    puntero = frase;

La otra manera que comentabas también es posible.
#383
Programación C/C++ / Re: ayuda rellenar ficheros C
26 Noviembre 2019, 18:17 PM
Todo depende de cómo te estén dando la información. Tienes que ser más específico...
Revisa la librería <stdio.h> y las funciones que tiene. Avanza algo, lo que puedas, y coloca tus avances entre etiquetas de Código GeSHi para poder ayudarte mejor.
#384
Programación C/C++ / Re: cadenas y uso de MAYUSCULA
25 Noviembre 2019, 02:39 AM
Las palabras en C se toman en un array de char, o lo que es lo mismo, una cadena de caracteres, un vector. Cada posición de la cadena contiene un caracter, pongamos el típico ejemplo: "hola mundo". Al guardar esto en C quedaría así:

char frase[] = "hola mundo";
// Internamente queda guardado como:
// frase = |'h'|'o'|'l'|'a'|' '|'m'|'u'|'n'|'d'|'o'|'\0'|

El último es un carácter especial que utiliza C para saber donde acaba la cadena. Se pone implícitamente.
Entonces si haces:

printf("%s", frase); // muestra: "hola mundo" sin las comillas
//pero si haces:
printf("%s", frase+5); // muestra: "mundo" sin las comillas porque empieza a mostrar 5 posiciones mas a la derecha


Como puedes usar las funciones que te dije anteriormente, sólo tienes que crear un puntero que como su nombre indica apunta y hacer que apunte al comienzo de la última palabra:

char frase[] = "hola mundo";
char *puntero = strrchr(frase, ' '); // devuelve un puntero apuntando al ultimo espacio de la frase
++puntero; // incrementas el puntero para que apunte a la primera letra de la palabra
while(*puntero != '\0'){ // mientras no acabe la cadena
    *puntero = toupper(*puntero); // modificas el valor de cada celda por su mayuscula correspondiente
    ++puntero; // sigues avanzando
}


Al final resulta que prácticamente te lo he dado hecho pero me parecía que sino te ibas a liar con lo de punteros, el asterisco, los incrementos, las funciones esas, etc.
El puntero es como una variable que en vez de guardar un valor como tal, guarda una posición de memoria. Para acceder al contenido de dicha posición de memoria se utiliza el asterisco (lo que se conoce como desreferenciar el puntero).

char letra = 'a';
char *puntero = &letra; // el asterisco determina que se trata de un puntero y el & devuelve la direccion de memoria de la variable (letra en este caso)
printf("%d", puntero); // posicion de memoria de la variable letra
printf("%c", *puntero); // contenido de la variable a la que apunta el puntero (letra)


Estoy intentando aclararlo pero cuanto más escriba creo que más complejo lo voy a dejar así que si hay cosas que de momento no entiendes, no te preocupes. Ya irás avanzando en el curso y al final verás como esto es una tontería.

PD: Para pedir valores se suele usar <scanf()> pero si se trata de una cadena, lo recomendable y seguro es hacerlo con <fgets()>:

char cadena[50]; // cadena de longitud maxima 50
printf("Introduce una cadena: ");
fgets(cadena, 50, stdin);

Lo malo de esta función es que también guarda el ENTER que pulsas al final por lo que si introduces "hola", en la cadena se guardaría como:
cadena = |'h'|'o'|'l'|'a'|'\n'|'\0'|
La '\n' determina un salto de línea. Para eliminar eso es muy sencillo ahora que ya te he mostrado como funciona <strrchr()>:

// supongamos que el usuario introduce "hola mundo". La cadena quedaria:
char cadena[] = "hola mundo\n"; // recordemos que siempre acaba en '\0'
char *final = strrchr(cadena, '\0'); // busca el '\0' que siempre va a estar el ultimo
*(--final) = '\0'; // nos vamos una posicion para atras y ponemos el '\0' ahi para eliminar el '\n'

#385
Programación C/C++ / Re: cadenas y uso de MAYUSCULA
25 Noviembre 2019, 02:03 AM
No sé si tienes alguna restricción en cuanto a que tengas que implementarlo todo sin utilizar funciones que ya existen...
Si no es tu caso y puedes usar funciones tienes:
  • strrchr() de la librería <string.h> que te devuelve un puntero a la última coincidencia de un caracter dado.
  • toupper() de la librería <ctype.h> que convierte un caracter en mayúscula.

    Si no puedes usar dichas funciones y tienes que implementarlo tú, te recomendaría hacer una función que dado un <char[]>, te devuelva la posición (índice) en el que empieza la última palabra; y luego con un bucle vas convirtiendo cada letra en mayúscula.
    En ASCII una letra minúscula vale 28 más que en mayúscula si no me equivoco por lo que si haces:

    char minuscula = 'a';
    char mayuscula = minuscula - 28; // esto deberia guardar 'A'

    // Sino siempre puedes hacer:
    char minuscula = 's';
    char mayuscula = minuscula - ('a' - 'A'); // esto deberia dar 'S'


    Es posible que si acabas de empezar, esto que te acabo de soltar te suene a chino y no entiendas nada. Si tienes alguna duda o no consigues avanzar en tu tarea, puedes poner el código en un mensaje entre etiquetas de Código GeSHi para que podamos ayudarte mejor.
#386
Cita de: yina07 en 24 Noviembre 2019, 23:05 PM
Como te habia dicho, lo intente hacer así pero me daba errores, asi como lo pones sigue dando errores, empieza en el cout de la linea 8, probe borrandolo y sigue dando errores en la linea siguiente y así, ahí no se como arreglarlo realmente, me estuve fijando y no se que es lo que esta mal.
Como te ha dicho @?0!,5^34, el error parece que es que hay un punto por ahí suelto en la línea del switch() (línea 17).
Si te da algún error más en las líneas del <cout> asegúrate de haber incluido la cabecera <iostream> y la línea "using namespace std;" porque son las encargadas de hacer que <cout>, <cin> y <endl> funcionen.


Cita de: @?0!,5^34 en 24 Noviembre 2019, 23:36 PM
Esta sentencia no sé si es válida.
salir = (opcion == 1);
Entiendo que (opcion == 1) es lo mismo que true, pero nunca ví utilizar expresiones así.

Si te da error ahí haz un if (opcion == 1) { salir = true; } else {salir = false;}
El else sobra pero por si lo modificas te lo dejo.
Y sobre esta sentencia, sí es válida. Como tú dices la comparación (opcion == 1) es una operación booleana por lo que el resultado sólo puede ser {true, false}. Dicho resultado se puede almacenar directamente en una variable como aparece ahí para ahorrarse los <if()>.
Es algo similar al operador ternario:
Código (cpp) [Seleccionar]

salir = (opcion == 1)?true:false;

pero que permite hacer la expresión todavía más sencilla.

Al final es lo mismo que cuando quieres hacer una función que devuelva un bool:
Código (cpp) [Seleccionar]

// La primera opcion seria:
bool esPar(int numero){
    bool par;
    if(numero % 2 == 0)
        par = true; // o bien hacer un return true
    else
        par = false; // y aqui un return false
    return par;
}

// La otra opcion un poco mas simple seria:
bool esPar(int numero){
    bool par = false;
    if(numero % 2 == 0)
        par = true;
    return par;
}

// Y la opcion aprovechando dicha propiedad quedaria:
bool esPar(int numero){
    return (numero % 2 == 0);
}

Al menos para mí parece más sencilla la última y más rápida de leer.
#387
Bueno a ver, hasta la línea 42 está bien. Pero el bucle... :xD :xD
Si te he puesto lo de:
Código (cpp) [Seleccionar]

bool salir = false;
int respuesta;

while(!salir){
    cout << "Hola" << endl;

    cout << "Desea salir (1 = Si / 0 = No): ";
    cin >> respuesta;

    salir = (respuesta == 1);
}

Era para que vieses un ejemplo sencillo de un programa que muestra "hola" cada vez que lo repites. Pero lo que tú quieres hacer no es que te muestre "hola" sino que te haga una operación con dos números.
A eso se refería tu profesor al decir que el programa debe ir dentro del <while()>.

En tu caso tendrías que coger TU PROGRAMA que es el que va de la línea 1 a la 43 y ponerlo donde está el "cout << "Hola" << endl;" de mi ejemplo.
El resultado sería el siguiente:
Código (cpp) [Seleccionar]

int main(){
    // Declaramos las variables antes del bucle porque si lo hacemos dentro las estaremos declarando cada vez que se repita el programa
    int numero1, numero2, resultado;
    int opcion;
    bool salir = false;

    while(!salir){
        cout<<"Que operacion desea realizar?"<<endl;
        cin>>opcion;

        cout<<"Introduzca un valor"<<endl;
        cin>>numero1;

        cout<<"Introduzca otro valor"<<endl;
        cin>>numero2;

        switch(opcion){ .
            case 1:
                resultado = numero1 + numero2;
                break;
            case 2:
                resultado = numero1 - numero2;
                break;
            case 3:
                resultado = numero1 * numero2;
                break;
            case 4:
                resultado = numero1 / numero2;
                break;
            default:
                cout << "La opcion no es valida" << endl;
        }
        cout << "El resultado es: " << resultado << endl;
        // AQUI TERMINA LO QUE SERIA TU PROGRAMA SIN REPETICIONES
        // Ahora ponemos la pregunta para repetir el programa
        cout << "Terminar programa (1 = Si / 0 = No): ";
        cin >> opcion; // podemos reutilizar la variable opcion para no tener que crear otra al principio. Si se crea otra tambien funciona bien
        salir = (opcion == 1);
    }
}

#388
Programación C/C++ / Re: Archivos usando fseek
24 Noviembre 2019, 19:25 PM
Coloca el código entre etiquetas de Código GeSHi...

Por lo que veo, la función <fseek()> para poder recibir un valor de offset (segundo parámetro), el fichero debe estar abierto en formato binario.
Modifica la apertura del archivo por:
Código (cpp) [Seleccionar]

// ruta_archivo que siga siendo la ruta de tu archivo
// r abre el archivo en modo lectura
// b abre el archivo en modo binario
archivo = fopen("ruta_archivo", "rb");


No sé si en C++ se podrá hacer de otra manera ya que parece que estás usando un método nativo de C.

PD: La condición del <while()> es una asignación, no una comparación, por lo que no te funcionará.
PD 2: Tienes un <switch()> con un único <case>... Para un único valor, acabas antes haciendo un condicional <if()>.
#389
Obviamente yo también tuve unos inicios y no me ofende que no sepas programar o que tengas errores básicos porque para eso es el foro, para ayudar. Lo que me molesta es que haya muchas personas que comentan ocasionalmente y no se molesten en poner los códigos entre etiquetas y más cuando siempre aconsejo usar dichas etiquetas (puedes comprobar en el otro post que hiciste AQUÍ que también te avisé de poner los códigos entre etiquetas y creo que lo hice con toda la educación que tengo).
Dicho esto, que no quiero que sea el comienzo de una pelea, sólo mostrar porque a veces no tengo tanta paciencia para repetir lo de las etiquetas, vamos al problema.
Ahora tu código ya tiene mejor pinta, lo que te falta es pedir al usuario una opción:
Cuando en la línea 9 preguntas qué operación realizar, lo que responda el usuario debe ir a la variable <opcion> y dicha variable no tiene que ser un array/vector. El array sería para almacenar a la vez todas las opciones (que eso es lo que tienes tú hecho en la línea 7). En tu caso debe ser una variable normal porque sólo contendrá 1 de esos 5 valores.
Y después de haber guardado la opción, es cuando hay que pedir los dos operandos. Los condicionales están bien, te faltaría hacer más para el resto de opciones, pero vas bien.

No sé si habrás visto el <switch>. Es otra estructura como el <if()> muy común para realizar menús y temas de opciones:
Código (cpp) [Seleccionar]

switch(opcion){ // Segun lo que vale opcion...
    case 1: // ...si vale 1...
        resultado = numero1 + numero2; // ...hace esto
        break; //...y Sale. Si no se pone el break haria tambien las instrucciones del case 2, del 3... hasta el default o hasta encontrar un break
    case 2:
        resultado = numero1 - numero2;
        break;
    // todos los case que quieras con su numero de opcion correspondiente
    default: // ...si opcion no vale ninguna de las cosas anteriores...
        cout << "La opcion no es valida" << endl; // ...muestra esto
    // Como despues del default ya no hay mas opciones, el break es opcional.
}



Como veo que eso ya lo llevas bastante bien, aprovecho para explicarte lo del bucle.
Lo normal es hacerlo con una estructura <do{} while()> pero si te mandan hacerlo con un <while()> también se puede adaptar.
Para ello hay que tener una condición que será la que determine si el programa se repite o no. En tu caso es 1=sale 0=repite. Esto se puede hacer con otra variable <int> por ejemplo llamada <salir> o con una variable de tipo <bool salir> que valdrá true/false (1/0).

Te hago un pequeño programa muy sencillo para que veas su uso y después aplicarlo tú a tu problema:
Código (cpp) [Seleccionar]

// ALTERNATIVA 1: Usando un int
int main(){
    int salir = 0; // le damos el valor 0 para que la primera vez que se ejecuta, funcione.

    // La condicion para finalizar el programa es que salir valga 1. Entonces el programa se repetira mientras salir sea distinto de 1:
    while(salir != 1){
        cout << "Hola" << endl;

        cout << "Desea salir: (1 = Si / 0 = No): ";
        cin >> salir;
    }
}

// ALTERNATIVA 2: Usando un bool de forma un poco rara
int main(){
    bool salir = false;

    while(!salir){ // esto es equivalente a decir: salir == false
        cout << "Hola" << endl;

        cout << "Desea salir: (1 = Si / 0 = No): ";
        cin >> salir; // Si no recuerdo mal, el 0 lo guardara como false y cualquier otro numero lo guardara como true
    }
}

//ALTERNATIVA 3: Usando un bool de forma mas facil de entender
int main(){
    bool salir = false;
    int respuesta; // para guardar la respuesta del usuario y no hacerlo directamente en bool

    while(!salir){
        cout << "Hola" << endl;

        cout << "Desea salir (1 = Si / 0 = No): ";
        cin >> respuesta;
        // Ahora si la respuesta vale 1, salir debe valer true y si vale 0, salir debe valer false
        salir = (respuesta == 1); // Asi valdra true cuando respuesta sea 1 y false en cualquier otro caso
    }
}


Como ves hay muchas formas de hacerlo y esto sólo usando el while(), si usas el <do while()> tendrás el doble de alternativas. Lo que todas tienen en común es que si el usuario no introduce ni 1 ni 0, el programa tomará una decisión según la alternativa.
#390
Al final lo que tienes que hacer es un bucle para poder repetir el juego.
Código (cpp) [Seleccionar]

int contadorPartidas = 0;

do{
    reiniciarPuntuaciones(); // poner las puntuaciones y todo a 0 para cada vuelta
    jugar(); // el proceso del juego
    guardarPuntuacion(); // al acabar guardas la puntuacion segun el sistema que estes utilizando
    ++contadorPartidas; // incrementas el contador de partidas jugadas
}   while(contadorPartidas < LIMITE_PARTIDAS); // Todo esto se repite mientras el numero de partidas jugadas sea menor al minimo que desees

Como no veo tu código, sólo te queda adaptar esta versión simplificada a tu programa.
Suerte :-X