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 - MAFUS

#201
Programación C/C++ / Re: Proyecto Dev C
9 Diciembre 2018, 20:58 PM
while(datos[i] != '$')
{
    RS232_PollComport(cport_nr, buf, 1);
    datos[i]=buf[0];
}
i++;

Tienes un problema con la adquisición de datos, aquí un ejemplo:
Vas adquiriendo datos pero terminan siempre en el mismo sitio así que realmente es cómo si no recibieras nada.
#202
Para eso no debes usar la técnica de letra a letra sino que deberás separar las palabras con un array de strings y a cada palabra que consigas mirar si ya existe en el array.
#203
Si el enunciado es mostrar una frase palabra a palabra lo puedes simplificar tanto como:
Recorre la frase de principio a fin. Si encuentras un espacio escribe un avance de línea, en caso contrario escribe el carácter que has encontrado.


#include<stdio.h>
#include<string.h>
#include<ctype.h>

int main() {
char cadena[100];
printf("Ingrse una frase: ");
scanf("%100s", cadena);

for(int i=0; i<strlen(cadena); ++i)
        putchar(isblank(cadena[i])? '\n' : cadena[i]);
}
#204
Supongo que con este te irá bien.
Va comprobando desde la primera hasta la penúltima columna si las siguientes son iguales a ellas. En cuánto detecta que dos elementos no son iguales va no pierde más tiempo y va a buscar la siguiente columna. Si detecta que dos columnas son iguales se detiene e informa de ello.
Hay que usar stdbool, pero se puede cambiar el bool por int y true y false por 1 y 0 respectivamente.

bool columnas_iguales(int matriz[][COLUMNAS]) {
    bool retval = false;

    for(int i=0; !retval && i<COLUMNAS-1; ++i) {
        for(int j=i+1; !retval && j<COLUMNAS; ++j) {
            int m;
            for(m=0; m<FILAS; ++m) {
                if(matriz[m][i]!=matriz[m][j])
                    break;
            }
            if(m==FILAS)
                retval = true;
        }
    }

    return retval;
}
#205
stdin no és un archivo de texto al uso. Se ve como archivo por la forma en que UNIX maneja los componentes de la máquina (cómo se ha dicho C se creó para programar UNIX y tiene esas reminiscencias).

stdin es un stream así que no tiene final: se vacía a petición del S.O. pero se llena por circunstancias ajeno a él. De alguna forma siempre se está en el inicio de stdin.

Al decirle a fseek que vaya al final de stdin lo que se hace es ir al final del buffer, entiéndase el final en ese justo momento, pero lógicamente se vuelve a encontrar en su posición inicial listo para llenarse de nuevo con cada nuevo dato que se entre.

Imaginaros una cola se escribe por el final y se lee por el principio. Ahora imaginaros que podéis mover el puntero de lectura con fseek al final. Todo lo que hay al inicio desaparece y la cola aparece vacía.
#206
Me he tomado la libertad de refactorizar tu función y me ha quedado algo así:

Código (c++) [Seleccionar]
setClientes eliminarClientes (setClientes variosClientes ) {
   bool encontrado = false;
   int i;
   char entradaDatos[22];
   
   const int tamNumCuenta = 10;
   
   switch(menu1()) {
   case 1:
       leerCadena("Introduzca el DNI\n", entradaDatos);
       for(i=0; i<variosClientes.numClientes; i++) {
           if(strcmp(variosClientes.Clientes[i].DNI, entradaDatos)==0) {
               encontrado = true;
               break;
           }
       }
       break;
       
   case 2:
       leerCadena("Introduzca el numero de cuenta\n", entradaDatos);
       if(strlen(entradaDatos) != tamNumCuenta) {
           cout<<"El número de cuenta introducido no tiene el formato correcto."<<endl;
       }
       else {
           for(i=0; i<variosClientes.numClientes; i++) {
               if(strcmp(variosClientes.Clientes[i].numCuenta, entradaDatos)==0) {
                   encontrado = true;
                   break;
               }
           }
       }
       break;
   }
   
   if(encontrado) {
       cout<<"\nEl cliente ha sido eliminado del sistema";
       for(int j=i; j<variosClientes.numClientes-1; j++) {
           variosClientes.Clientes[j] = variosClientes.Clientes[j+1];
       }
       --variosClientes.numClientes;
   }
   
   return variosClientes;
}


Puede haber errores, no la he probado.
Parte importante: pon el prototipo int menu1(); fuera de la función, justo después de los includes. Los prototipos no se ponen dentro de las funciones, se puede pero muy mala práctica.
He quitado los bucles porqué no querrás que tu cliente se encuentre en un bucle sin fin si le han pasado un DNI o cuenta que no está en la tabla y se vea obligado a eliminar una entrada buena sólo para que el programa siga ejecutando.

Por otra parte: recibes toda la estructura de datos y devuelves toda la estructura de datos. Depende de lo grande que sea eso es mucho movimiento de datos. Te convendría usar referencias o punteros.
Además: a menos que copies en otro sitio una la nueva estructura modificada te convendría hacer que la función modificara la estructura del argumento directamente.
#207
Como primera orden del if tienes una comparación, no una asignación
x==false;
Lo que haces ahí es comparar x con false y el resultado se pierde. No se cambia el valor de x. Es decir: en vez de == debe haber =.

Para evitar tu próximo posible fallo lógico:
Las dos cadenas a comparar deben ser exactamente iguales
Es decir que si numCuenta tiene un salto de línea porque lo has capturado con un fgets (y esa función obtiene saltos de línea) y comparacionCuenta no tiene saltos de línea o viceversa, las dos cadenas no serán iguales y la comprobación fallará.
#208
Tu fallo puede estar en esta línea, de hecha en esta línea hay un fallo gordo que suele pasar desapercibido:
}else if (x=true&&(i==n-1)){

Si te fijas asignas true a x: x=true

Para evitarte esto: cuando se evalúa una variable para C o C++ devuelve false si de alguna forma vale 0 (que valga false, 0, NULL, '\0'), para todo lo demás vale true.

Todo esto viene a decir que lo podrías haber escrito:
}else if (x && (i==n-1)){
#209
Veo que conoces malloc así que no hay problema en que uses memoria dinámica.
A la hora de generar el array házlo de forma dinámica.
El prototipo de la función que recibiera tu array sería éste:

void muestra(int **array, int filas, int columnas);

Esto es así porqué si le pasas un array estático estás obligado a darle todas las dimensiones menos la de mayor peso. Esto es así porque C necesita conocer el tamaño de los objetos que va a usar, y cómo se escapa de la explicación de esta respuesta te lo tendrás que creer.

Ahora llega la hora de crear el array. Suponiendo que el número de filas ya está en n_filas y el número de columnas ya está en n_columnas, lo dimensionas de esta forma:

int **mi_array = malloc(n_filas * sizeof(int*));

for(int i = 0; i < n_filas; ++i)
    mi_array[i] = malloc(n_columnas * sizeof(int));


A la hora de darle un dato a una posición cualquiera del array suponiendo m el número de fila, n el número de columna y x el dato a guardar:

mi_array[m][n] = x;

Lo mismo que para mostrarlo:

printf("%d", mi_array[m][n]);

Y a la hora de pasar el array a la función:

muestra(mi_array, n_filas, n_columnas);

Ahora pensarás:
Pero si C necesita saber el tamaño de un objeto para poderlo usar ¿Por qué se le pasa mi_array sin dimensión alguna, en vez de hacer mi_array[][20], por ejemplo?

La respuesta es que todos los punteros tienen el mismo tamaño. Todos.

Así que te aseguras, de esta forma, que puedes pasarle a esta función un array con un tamaño arbitrario de sus dimensiones que te va a funcionar siempre que los valores que le pases a filas y columnas sean los que realmente tiene dicho array.

Muy importante, eso sí, cuándo dejes de utilizar el array debes liberarlo y eso se debe hacer desde dentro a afuera. Así:

for(int i = 0; i < n_columnas; ++i)
    free(mi_array[i]);
free(mi_array);
#210
Edita el post y pon el código entre etiquetas GeSHi. Las tienes justo encima de la caja de texto.