2014-07-25 41 views
1

我習慣於Java,但學習C++和作爲一個實驗我試圖創建一個庫,將用用戶定義的導入規格將CSV文件讀取到2d數組中,將數組打印到控制檯,然後編寫數組到一個單獨的文件。在自定義庫中操作2d C++數組 - 獲取行數?

我被困在如何確定在創建陣列,打印數組和寫入數組時循環通過2d數組的行數(y軸)。我已經得到了x軸值,並且我一直在擺弄這個:

int y = sizeof(arr)/sizeof(arr[0]); 

試圖獲得它。當我在一個編譯的cpp main中測試代碼時,它得到了正確的行數,但現在我已經將函數移動到了包含的庫中,它將0賦值給y!

爲什麼不同,我該如何解決?在下面的例子中,我測試了一個有6個字段和4條記錄的矩陣,所以我期待4分配給y值。

由於我已經把問題縮小到這個變量,這裏是一個(希望)SSCCE我怎麼得到y。

頭文件:

#ifndef CSV_IO_H 
#define CSV_IO_H 

#include <string> 

using namespace std; 

class csv_io 
{ 
    public: 
     static void csv_to_dbl_arr(string, double arr[][6], char, char); 
     static void print_dbl_arr(double arr[][6]); 
}; 

#endif 

所包含的庫:

#include "csv_io.h" 
#include <stdlib.h> 
#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <iomanip> 

using namespace std; 

void csv_io::csv_to_dbl_arr(string inf, double arr[][6], char dlm, char sep) 
{ 
    ifstream ifs; 
    string row, col, val; 
    int i = 0; 
    int j = 0; 

    ifs.open(inf.c_str()); 
    if(ifs.is_open()) 
    { 
     while(ifs.good()) 
     { 
      getline(ifs, row, sep); 
      stringstream col(row); 

      while(col.good()) 
      { 
       getline(col, val, dlm); 
       arr[i][j] = atof(val.c_str()); 
       j++; 
      } 
      j = 0; 
      i++; 
     } 
    } 
    ifs.close(); 
} 

void csv_io::print_dbl_arr(double arr[][6]) 
{ 
    int x = sizeof(arr[0])/sizeof(double); 
    int y = sizeof(arr)/sizeof(arr[0]); 

    cout << "x: " << x << endl << "y: " << y << endl; 
} 

的main.cpp中

#include "csv_io.h" 
#include "csv_io.cpp" 
#include <stdlib.h> 

using namespace std; 

int main() 
{ 
    double d_arr[4][6]; 

    string inf = "file_i.txt"; 

    char in_dlm = ','; 
    char in_sep = '\n'; 

    csv_io::csv_to_dbl_arr(inf, d_arr, in_dlm, in_sep); 
    csv_io::print_dbl_arr(d_arr); 

    return 0; 
} 

file_i.txt:

1,1,1,1,1,1 
2,2,2,2,2,2 
3,3,3,3,3,3 
4,4,4,4,4,4 

我知道我可以做一個反&跟蹤csv_to_dbl_arr的行數,但我想弄清楚我使用y的表達,所以我可以用它在飛行時不必在主要位置聲明。

+0

我不知道你的問題的答案。但我知道的是,C++很適合避免這種問題。我寧願使用一個向量>而不是double [] [6]。那麼y是arr.size(),x是你定義的常量。 –

回答

1

void print_dbl_arr(double arr[][6])相當於
void print_dbl_arr(double (*arr)[6])

所以

  • sizeof(arr)是一個指針
  • sizeof(arr[0])的大小的double (&)[6]所以6 * sizeof double大小。

您可以使用模板,並通過數組引用,以獲得大小爲以下幾點:

template <std::size_t N, std::size_t M> 
void print_dbl_arr(double (&arr)[N][M]); 

使用std::vector/std::array更直觀。

1
double d_arr[4][6]; 

void csv_io::print_dbl_arr(double arr[][6]) 
    { 
     int x = sizeof(arr[0])/sizeof(double); 
     int y = sizeof(arr)/sizeof(arr[0]); 

     cout << "x: " << x << endl << "y: " << y << endl; 
    } 

csv_io::print_dbl_arr(d_arr); 

在您通過陣列d_arrprint_dbl_arr,它崩解爲指針(double (*arr)[6])。所以sizeof(arr)在32位平臺上是4。並且arr[0]是六個雙打的一維數組,其大小爲48(假設sizeof(double)爲8)。整數除法4/48的結果爲零。

同一件事情發生在一維數組(在兩種情況下,爲最高維度指定[])。這就是爲什麼我們需要傳遞數組的元素數作爲其他參數,以便被調用者可以知道它。

int arr[4]; 
void f(int arr[], int n) 
{ 
    // The wrong way 
    // arr is decayed to a pointer, int *arr. 
    // for (size_t i = 0; i < sizeof(arr); ++i) 
    // { 
    // // iterate over the array 
    // } 

    // The correct way 
    for (size_t i = 0; i < n; ++i) 
    { 
     // iterate over the array 
    } 
} 
1

你逝去一個整數/浮點值/雙陣列的功能,這意味着要傳遞陣列的唯一的基地址(因爲陣列名稱表示的基地址)

在下面的功能:

void csv_io::print_dbl_arr(double arr[][6]) 
{ 
    int x = sizeof(arr[0])/sizeof(double); // here you are dividing sizeof(address of array) with sizeof(double) 
    // because arr and arr[0] both represents the base address of the array in 2D array 
    int y = sizeof(arr)/sizeof(arr[0]); // Its indirectly means that dividing the size of base addresses 
    cout << "x: " << x << endl << "y: " << y << endl; 
} 

爲了避免每當要傳遞一維數組的函數這種類型的錯誤你應該通過的總的沒有該數組中的元素。對於二維數組,您需要將行和列值傳遞給具有數組基地址的函數。

希望這會幫助你!