Cantidad de caracteres en un arreglo y cortar una cadena

Iniciado por josri, 15 Marzo 2013, 07:28 AM

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

josri

Hola saludos a todos, les comento, hize un programa en c++ el cual lee de un archivo el nombre apellido y matricula de varios alumnos, algo mas omenos asi...

JOSE|HERNANDEZ|203303035
CRISTINA|DIAZ|206303660
SERGIO|GONZALEZ|206201478

En el programa para leer cada campo hice lo siguiente...

for(i=0; i<k; i++)
   {
       fscanf(archivo,"%[^|]|%[^|]|%[^\n]\n",&nombre,&apellido,&matricula);
   }

En un while anterior ya obtuve la cantidad de lineas que tiene el archivo y lo asigne a k para que leyera cada linea, mi duda es la siguiente. Como puedo leer otro campo para que este contenga la posicion inicial de cada registro, por ejemplo en la primera lectura obtendria un 0 ya que JOSE empieza en 0 y en el segundo campo obtendria un 25 que es donde empieza CRISTINA y asi consecutivamente.

La segunda pregunta es como puedo leer el apellido pero que solo quede en un registro de 6 posiciones, por ejemplo:HERNANDEZ se guardaria como HERNAN o DIAZ se guardaria como DIAZ**(* = espacios en blanco), intente hacer esto con substr pero me marca error.

Los campos los declare de la siguiente manera...

char nombre[17][15];
char apellido[17][17];
char matricula[17][10];

Mi programa lo que hace es ordenar los registros en forma ascendente por "la matricula -+- pocision de inicio de ese registro" y escribirlo en un archivo nuevo.
Luego volverlo a ordenar pero ahora por el apellido junto con su matricula y escribirlo en un archivo nuevo. Todo eso ya lo hize, lo que me falta es como obtener la posicion de inicio de cada registro y si se puede meter los apellidos en campos de 6 posiciones.
Espero puedan hecharme un cable... :P

PD. Mi codigo puede ser penoso pero funciona a tirones  :xD, lo digo por si a alguno le arden los ojos al leerlo XD.

naderST

#1
http://www.cplusplus.com/reference/cstdio/ftell/ La función ftell te permite obtener la posición actual en el archivo, entonces antes de leer una linea haces ftell y lo vas almacenando en un arreglo.

En el fscaf tienes un detalle ya que tu tienes declarado un arreglo de strings y todos los registros los estás almacenando en el primer elemento de dicho arreglo, deberías llevar un contador y leer así:

nombre[contador]

rir3760

Cita de: josri en 15 Marzo 2013, 07:28 AMLa segunda pregunta es como puedo leer el apellido pero que solo quede en un registro de 6 posiciones, por ejemplo:HERNANDEZ se guardaria como HERNAN o DIAZ se guardaria como DIAZ**(* = espacios en blanco), intente hacer esto con substr pero me marca error.
Lo ideal seria que utilizaras solo las facilidades de la biblioteca estándar de C++ como la función getline y la clase string ...

Pero si piensas utilizar funciones como fscanf una solución es leer del archivo el apellido y almacenarlo en una variable temporal (eso para evitar ciertos detallitos de la función), a continuación lees del temporal los caracteres necesarios y los imprimes con el formato deseado.

Un ejemplo sencillo en C donde "temp" es la variable temporal y "campo" la ubicación final del apellido:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
   char *ape[] = {
      "HERNANDEZ",
      "DIAZ",
      "GONZALEZ",
   };
   char temp[100];
   char campo[100];
   int i;
   
   for (i = 0; i < 3; i++){
      sscanf(ape[i], "%[^|]", temp);  /* archivo ==> temp  */
      sprintf(campo, "%-6.6s", temp); /*    temp ==> campo */
     
      printf("\"%s\"\n", campo);
   }
   
   return EXIT_SUCCESS;
}


Su salida es:
"HERNAN"
"DIAZ  "
"GONZAL"


La cadena de formato "%-06.6s" se utiliza para indicar:
1) "-", alineación a la izquierda.
2) "6.", impresión con seis caracteres de ancho, los faltantes serán espacios.
3) ".6", se leen del argumento (en este caso temp) un máximo de seis caracteres.

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

josri

Cita de: rir3760 en 15 Marzo 2013, 18:29 PM


Cita de: naderST en 15 Marzo 2013, 16:37 PM
nombre[contador]

gracias a los dos por responder, hoy por la tarde o noche aplico sus consejos y les cuento como me fue

josri

Cita de: rir3760 en 15 Marzo 2013, 18:29 PM

hola, intente hacer lo que mencionaste pero me imprime "basura" o solo una letra creo que mi problema puede estar en la forma que lo implemento, no se si se deba a los arreglos que los declare como matriz... te muestro parte de mi codigo....

Citar
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{

    char nombre[17][15];
    char apellido[17][17];
    char matricula[17][10];
    char aux[20];
    char aux1[20];
    int i,j,k;
    float comp;

    char ofilename[] = "secundario.txt";
    FILE *ofp;
    ofp = fopen(ofilename,"w");

    char ofilename1[] = "primario.txt";
    FILE *ofp1;
    ofp1 = fopen(ofilename1,"w");

    char ifilename[] = "lista.txt";
    FILE *archivo;
    archivo = fopen(ifilename,"r");

    k=0;
    while(!feof(archivo))
    {
        fscanf(archivo,"%[^|]|%[^|]|%[^\n]\n",&nombre[k],&apellido[k],&matricula[k]);
        k=k+1;
    }

    for(i=0; i<k; i++)
    {
        fscanf(archivo,"%[^|]|%[^|]|%[^\n]\n",&nombre,&apellido,&matricula);
    }
.
.
.
.
//aqui es donde ordena la matricula junto a su apellido, intente cambiar la declaracion de apellido pero al hacerlo ma marca error en todo esto por eso mejor deje las declaraciones tal cual.

for(j=0; j<k-i; j++)
        {
            comp = strcmp(matricula[j], matricula[j+1]);
            if(comp > 0)
            {
                strcpy(aux,matricula[j]);
                strcpy(aux1,apellido[j]);

                strcpy(matricula[j],matricula[j+1]);
                strcpy(apellido[j],apellido[j+1]);

                strcpy(matricula[j+1],aux);
                strcpy(apellido[j+1],aux1);
            }
        }


en el primer for es donde te menciono que me gustaria cargar solo los primeros 6 caracteres del apellido. Por cierto use la instruccion que me habian mencionado en el inicio para la longitud de cadenas pero solo me daba la longitud del archivo completo XD

naderST

while(!feof(archivo))
    {
        fscanf(archivo,"%[^|]|%[^|]|%[^\n]\n",&nombre[k],&apellido[k],&matricula[k]);
        k=k+1;
    }

    for(i=0; i<k; i++)
    {
        fscanf(archivo,"%[^|]|%[^|]|%[^\n]\n",&nombre,&apellido,&matricula);
    }


1. Antes de leer los registros debes hacer rewind(archivo) para posicionarte al inicio del archivo.

2.  fscanf(archivo,"%[^|]|%[^|]|%[^\n]\n",&nombre,&apellido,&matricula); como te mencioné en el otro post solo te almacena en el primer elemento del arreglo, debes hacer lo siguiente: fscanf(archivo,"%[^|]|%[^|]|%[^\n]\n",nombre[k],apellido[k],matricula[k]);