0

Estoy trabajando en un programa para convertir archivos en formato .PCD a formato .OFF, para lo cual necesito leer el archivo. Es como leer un .txt y borrar el header pero adicional borrar la 4 columna de datos, hasta el momento he conseguido eliminar el header pero no logro eliminar la cuarta columna.

El formato es algo así:

 #.PCD v.7 - Point Cloud Data file format  
VERSION .7  
FIELDS x y z rgb  
SIZE 4 4 4 4  
TYPE F F F F  
COUNT 1 1 1 1  
WIDTH 213  
HEIGHT 1  
VIEWPOINT 0 0 0 1 0 0 0  
POINTS 213  
DATA ascii  
0.93773 0.33763 0 4.2108e+06  
0.90805 0.35641 0 4.2108e+06  
0.81915 0.32 0 4.2108e+06  
0.97192 0.278 0 4.2108e+06  
0.944 0.29474 0 4.2108e+06  
0.98111 0.24247 0 4.2108e+06  
0.93655 0.26143 0 4.2108e+06  
0.91631 0.27442 0 4.2108e+06  
0.81921 0.29315 0 4.2108e+06   
0.90701 0.24109 0 4.2108e+06  
0.83239 0.23398 0 4.2108e+06  
0.99185 0.2116 0 4.2108e+06  
0.89264 0.21174 0 4.2108e+06  
0.85082 0.21212 0 4.2108e+06  
0.81044 0.32222 0 4.2108e+06  
0.74459 0.32192 0 4.2108e+06  
0.69927 0.32278 0 4.2108e+06  
0.8102 0.29315 0 4.2108e+06  
0.75504 0.29765 0 4.2108e+06  

La cuarta columna que necesito eliminar es la que comienza con el 4.

y el codigo que tengo para eliminar el header este el siguiente:

#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <iostream>
#include<stdlib.h>
#include<string.h>
#include<fstream>
using namespace std;
int main()
{
int archivo;
char caracter;
long tamanno_archivo;

archivo=open("prueba.pcd", O_RDWR | O_BINARY);
if(archivo==-1) printf("Error al abrir archivo.\n");
tamanno_archivo=filelength(archivo);
for(long pos=1; pos<tamanno_archivo; pos++)
{
lseek(archivo, pos, 0);
read(archivo, &caracter, sizeof(char));
lseek(archivo, pos-185, 0);
write(archivo, &caracter, sizeof(char));
}
chsize(archivo, tamanno_archivo-185);
close(archivo);
}

De antemano gracias.

PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82

1 Answers1

0

Para empezar, dado que has etiquetado tu pregunta como C++, deberías usar correctamente el lenguaje:

  • Las cabeceras <stdio.h> , <stdlib.h> y <string.h> son de no de . Estas cabeceras disponen de una versión adaptada a C++ que tiene el prefijo c y carece de extensión. Si realmente necesitas usar las cabeceras de C (que nunca será el caso) debes usar los equivalentes de C++ <cstdio> , <cstdlib> y <cstring> . Lee este hilo para saber por qué.
  • No hay obligación de usar la cláusula using namespace std; pues es sólo es una ayuda a la escritura de código; si decides usar esta cláusula no lo hagas en el ámbito global, úsala en el ámbito más pequeño posible. Lee este hilo para saber por qué.
  • La función main, debe devolver un valor. Lee este hilo para saber por qué.
  • printf es la función de escritura en consola de C, en C++ se usa el objeto stream: std::cout.

Por otro lado, no se qué utilidades de lectura de archivos estás usando, pero no tiene pinta que estés usando <fstream>, te aconsejo encarecidamente usar esa utilidad ya que es muy fácil de usar y ya la estás incluyendo.

Propuesta.

Es como leer un .txt y borrar el header pero adicional borrar la 4 columna de datos.

Esto que propones es muy complicado de hacer, además de ser destructivo. No es nada práctico modificar archivos ya creados para cambiar datos de los mismos, en cambio es más común (y mejor) crear un archivo nuevo con datos del original, esto deriva en un código más fácil de mantener y entender además de no perder el archivo original.

Mi propuesta es que leas los datos línea a línea y vuelques en un archivo nuevo sólo la parte que te interesa:

#include <fstream>
#include <cctype>

int main()
{
    std::ifstream original{"original.pcd"};
    std::ofstream salida{"salida.off"};

    if (original && salida)
    {
        std::string linea;
        std::getline(original, linea); // Leemos (e ignoramos) la primera línea.
        while (std::getline(original, linea)) // Leemos línea a línea.
        {
            // Las líneas de datos empiezan por número, las otras por texto.
            if (std::isalpha(linea[0]))
            {
                salida << linea << '\n';
            }
            else
            {
                // Las columnas parecen separadas por espacio.
                // Nos quedamos con los datos hasta el último espacio.
                auto ultimo_espacio = linea.rfind(' ');
                salida << linea.substr(0, ultimo_espacio) << '\n';
            }
        }
    }
    else
    {
        std::cout << "No se pudo abrir los archivos\n";
    }

    return 0;
}
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82