2010-02-15 9 views
5

Hola tengo un archivo de texto que contiene dos matrices y un valor (todos los números enteros) como estoregresar dos matrices creadas en C++

3 90 22 5 60 33 24 

donde el primer número representa la cantidad de números enteros a leer en. I puede leer en todo esto en una función. ¿Necesito varias funciones para poder utilizar las diferentes matrices y la primera variable?

ifstream in(SOMEFILE.dat); 
    if (!in) { 
    cerr << "Cannot open file.\n"; 
    return -1;} 
    in >> VAR; 
    A=new int[VAR]; 
    B=new int[VAR]; 
    for(int i=0 ;i<VAR;i++){ 
     in >>A[i]; 
    } 
for(int i=0 ;i<VAR;i++){ 
     in >>B[i]; 
    } 

     in.close(); 

anterior es el código que tengo hasta ahora y esto podría funcionar en la función principal. ¿Tengo que escribir tres funciones para leer esta información en lo que puedo lo uso en mi programa o hay alguna manera, por ejemplo, podría enviar en tres punteros a una función?

I would like A to be 90 22 5 
B to be 60 33 24 
And VAR to be 3 

Gracias

Respuesta

2

Cada vez que desee agrupar elementos de datos, utilice una clase o una estructura. Por ejemplo, para pasar tres enteros como x, y, z las coordenadas ,:

struct Coord { 
    int x, y, z; 
}; 

y luego pasar a la estructura de la función:

void f(Coord & c) { 
} 

Lo mismo ocurre con las matrices, pero en su caso se haría que la estructura contenga punteros.

Su pregunta en realidad se abre enormes áreas de programación C++ que parece que no son conscientes. Algunas cosas que se deben leer antes de ir más lejos:

  • el concepto de estructuras, como se indicó anteriormente
  • constructores y destructores de estructuras
  • cuándo y cuándo no usar asignación de memoria dinámica
  • uso de contenedores de la biblioteca estándar de C++ como std :: vector

Esto puede parecer mucho, pero una vez que tenga un agarre clara sobre éstos, se encuentra la programación C++ mucho, mucho más fácil y más seguro.

+0

¡Muchas gracias! De hecho, sé un poco de lo anterior. Sin embargo, el curso que tomé en C++ siempre usaba clases en ejemplos con listas enlazadas y simplemente no pensé en ello en este ejemplo donde no necesito las diferentes matrices juntas más adelante en el código. Entiendo los conceptos, pero me falta la experiencia para usarlos sabiamente ... –

+1

@mrbuxley Gah! La lista enlazada! ¡Maldición de todos los programadores aprendices! Para mis opiniones sobre las malditas cosas, vea http://punchlet.wordpress.com/2009/12/27/letter-the-fourth/ –

+0

(= Lo que en realidad estoy haciendo es volver a escribir un código de trabajo para hacerlo lo más eficiente posible Un poco fuera de tema aquí. Pero debería ir con vectores o matrices dinámicas si estamos hablando de tamaños de matriz de 256 * 256? –

1

La forma más fácil es definir un tipo, por ejemplo una estructura, que representa los datos de una línea:

struct MyMatrix 
{ 
    int size; 
    int *a; 
    int *b; 
}; 

luego escribir una función que lee uno de esos casos de una línea de texto:

struct MyMatrix load_matrix(std::ifstream& stream) 
{ 
    MyMatrix m; 

    stream >> m.size; 

    m.a = new int[m.size]; 
    for(int i=0 ;i < m.size; i++) 
     stream >> m.a[i]; 

    m.b = new int[m.size]; 
    for(int i=0 ;i < m.size; i++) 
     stream >> m.b[i]; 

    return m; 
} 

Este código carece de comprobación de errores, pero se puede añadir que. Recuerde que la asignación de memoria puede fallar.

0

o simplemente utilizar params por referencia.

int theFunction(int*& arrayA, int*& arrayB){ 
    int size; 
    // ... 
    arrayA = new int[size]; 
    arrayB = new int[size]; 
    // ... 
    return size; 
} 
0

Cuando se desea devolver varios elementos que se pueden utilizar ya sea los parámetros de salida adicionales en sus funciones (pasados ​​por referencia) o devolver una tupla. Tiendo a preferir la opción posterior ya que resulta en un código más legible.

En lugar de administrar manualmente la memoria de sus matrices con new y delete[], puede usar un std::vector para lograr un comportamiento equivalente. Cada vector almacena su propio tamaño para que no tenga que devolver una variable adicional para eso.

En resumen, en este caso puede devolver una tupla de dos vectores. En la biblioteca estándar, las tuplas de dos elementos se representan con la clase std::pair. Por lo tanto, su función devolverá un par de vectores: std::pair<std::vector<int>, std::vector<int> >. Dado que es mucho para escribir, es mejor utilizar un typedef.

Esta es una posible implementación de su función. Tenga en cuenta que se pueden evitar bucles escritos manualmente gracias a la clase estándar istream_iterator:

typedef std::pair<std::vector<int>, std::vector<int> > Data; 
Data read(std::ifstream & ifs) 
{ 
    int n; 
    ifs >> n; 
    typedef std::istream_iterator<int> in_it; 

    std::vector<int> a(n); 
    std::copy(in_it(ifs), in_it(), a.begin()); 

    std::vector<int> b(n); 
    std::copy(in_it(ifs), in_it(), b.begin()); 

    return Data(a, b); 
} 

y esto es cómo utilizaría su función. Observe que no devuelve el tamaño implícitamente, pero puede recuperarlo fácilmente a través del std::vector::size().

int main() { 

    std::ifstream ifs("SOMEFILE.txt"); 
    Data data = read(ifs); 

    unsigned int n = data.first.size(); 
    std::vector<int> & a = data.first; 
    std::vector<int> & b = data.second; 

    return 0; 
} 

EDIT: sugerencia de utilizar mejor y un dedicado struct escalas de Neil conduce a código más legible, por lo que no debes dejar de considerar que también. En este caso, su estructura sería:

struct Data { 
    std::vector<int> a, b; 
}; 

Y su función main sería idéntico, excepto que usted tiene que reemplazar first y second con a y b.