2010-05-21 87 views
8

編輯:實施詹姆斯霍普金的建議後,我仍然得到「無效名稱null」的警告,這比那些奇怪的字符好得多。然後,我又回到了庫文檔中,結果發現,對於那個特定的函數,它的參數應該有一個非空字符串的元素,而不是一個名稱的大小。額外的字符串有其他目的。增加一個字符串後,代碼運行良好。這都是我的錯,我很抱歉。如何將字符串的向量傳遞給foo(char const * const * const)?

原帖:

嗨,

這是我的第一篇文章,所以請好的。我在這個論壇搜索和搜索,但我仍然無法找到答案。這個問題困擾了我超過一天,所以請給我一些幫助。謝謝。

我需要將一個字符串向量傳遞給庫函數foo(char const * const * const)。我不能通過& Vec [0],因爲它是一個指向字符串的指針。因此,我有一個數組並將c_str()傳遞給該數組。下面是我的代碼(aNames是串的向量):

const char* aR[aNames.size()]; 

std::transform(aNames.begin(), aNames.end(), aR, 
       boost::bind(&std::string::c_str, _1)); 
foo(aR); 

然而,現在看來,這會導致一些不確定的行爲:

如果我運行上面的代碼,然後函數foo亂扔一些警告非法字符('èI'blablabla)在aR。

如果我之前函數foo這樣的打印AR:

std::copy(aR, aR+rowNames.size(), 
      std::ostream_iterator<const char*>(std::cout, "\n")); 
foo(aR); 

然後,一切都很好。 我的問題是:

  1. 是否轉換將導致不確定的行爲?如果是這樣,爲什麼?

  2. 將字符串向量傳遞給foo(char const * const * const)的正確方法是什麼?

回答

1

好吧,這似乎對我來說。 c_str創建一個以null結尾的字符串數組,該字符串在下一個非常量字符串操作前保持不變。您將c_str指針存儲在const char *數組中。

我不是助推專家,所以問題可能在那裏,但我的猜測是,你的向量中的字符串是在與函數foo中預期的編碼不兼容的編碼。

從編碼的角度檢查您的代碼。

MY2C

5

由於foo只需要一個指針,我大膽猜測是,它需要一個NULL結尾的數組。爲aR分配一個額外的元素併爲其分配NULL。

我的建議是:

std::vector<const char*> c_strings; 
c_strings.reserve(aNames.size() + 1); 

std::transform(
    aNames.begin(), aNames.end(), 
    std::back_inserter(c_strings), 
    boost::bind(&std::string::c_str, _1) 
    ); 

c_strings.push_back(0); 
foo(&c_strings[0]); 
+0

+1好猜測。事實上,爲'foo'函數查找數組大小的唯一方法是找到空指針。 – 2010-05-21 16:28:08

+0

是的,很好的猜測!除非foo函數簽名不是真正的函數簽名。 @ user347208:那是確切的函數簽名嗎? – neuro 2010-05-21 16:33:54

+0

非常感謝您的幫助! @neuro:確切的函數簽名是int foo(const char * filename,char const * const * const rowNames,char const * const * const columnNames)。但是,正如我在本版中所說的,我很抱歉,我沒有仔細閱讀文件,浪費了時間。無論如何,非常感謝你的幫助! – EXP0 2010-05-21 19:21:16

1

試試這個:

std::vector<char*> arr(aNames.size()+1); 
for(size_t i = 0; i < aNames.size(); ++i) 
    arr[i] = aNames[i].c_str(); 
arr[arr.size()-1] = NULL; // just in case 
foo(&arr[0]); 
+1

不會編譯 - 'c_str'返回一個'const char *' – 2010-05-21 16:44:23

+0

好的。現在更改矢量以容納「const char *」元素。 – 2010-05-21 18:50:26