簡體   English   中英

char * to char []

[英]char* to char[]

我有char *,它具有固定(已知)寬度但不是空終止。

我想把它傳遞給LOG4CPLUS_ERROR("Bad string " << char_pointer); 但由於它的非null終止,它將打印出所有內容。

任何輕量級的方法得到"(char[length])*char_pointer"沒有執行副本的任何建議?

不,你必須進行深度復制並將其終止。 該代碼需要一個以null結尾的字符串,它表示以null終止符結尾的連續字符塊。

如果您的目標是打印這樣的字符串,您可以:

  1. 存儲最后一個字節。
  2. 替換為\\ 0。
  3. 打印字符串。
  4. 打印存儲的字節。
  5. 將存儲的字節放回字符串的最后位置。

將所有這些包裹在一個函數中。

我們開始討論char*char[]之間轉換的語義。 退后一步,你想做什么? 如果這是一個錯誤條件的簡單情況,將結構的內容流式傳輸到流,為什么不正確地執行?

例如

struct foo
{
  char a1[10];
  char a2[10];
  char a3[10];
  char a4[10];
};

// free function to stream the above structure properly..
std::ostream operator<<(std::ostream& str, foo const& st)
{
  str << "foo::a1[";
  std::copy(st.a1, st.a1 + sizeof(st.a1), std::ostream_iterator<char>(str));
  str << "]\n";

  str << "foo::a2[";
  std::copy(st.a2, st.a2 + sizeof(st.a2), std::ostream_iterator<char>(str));
  str << "]\n";

  :

  return str;
}

現在你可以簡單地流出一個foo實例,而不必擔心空終止字符串等!

真實的iostream

當你寫一個真正的iostream時,你可以使用ostream.write() ,它接受一個char*和一個大小來寫入多少字節 - 不需要空終止。 (實際上,字符串中的任何空字符都將寫入ostream,並且不會用於確定大小。)

記錄庫

在某些日志記錄庫中,您寫入的流不是真正的iostream。 Log4CPP就是這種情況。

但是,在Log4CPlus中 ,這就是matt正在使用的內容,您要寫入的對象是std::basic_ostringstream<tchar> (有關定義,請參閱loggingmacros.hstreams.h ,因為這些都不是顯而易見的。文件)。 只有一個問題:在宏LOG4CPLUS_ERROR ,第一個<<已經內置到宏中,因此他將無法調用LOG4CPLUS_ERROR(.write(char_pointer,length))或類似的東西。 不幸的是,我沒有看到一個簡單的方法,沒有解構LOG4CPLUS_ERROR錯誤宏並進入Log4CPlus的內部

我不確定你為什么要避免在這一點上復制字符串,因為你可以看到日志記錄庫里面有很多復制。 任何避免額外字符串副本的嘗試都可能是無根據的優化。

我將假設它是代碼清潔的問題,也許是確保復制發生在LOG4CPLUS_ERROR宏內部而不是外部的問題。 在這種情況下,只需使用:

LOG4CPLUS_ERROR("Bad string " << std::string(char_pointer, length));

我在我的工具包中保留了一個字符串引用類,僅用於這些類型的情況。 這是該類的大大縮寫版本。 我刪除了與此特定問題無關的任何內容:

#include <iostream>

class stringref {
public:
    stringref(const char* ptr, unsigned len) : ptr(ptr), len(len) {}

    unsigned length() { return len; }
    const char* data() { return ptr; }

private:
    const char* ptr;
    unsigned len;
};

std::ostream& operator<< (std::ostream& os, stringref sr) {
    const char* data = sr.data();
    for (unsigned len = sr.length(); len--; )
        os << *data++;
    return os;
}

using namespace std;

int main (int argc, const char * argv[])
{
    cout << "string: " << stringref("test", 4) << endl;
}

或者,在您的情況下:

LOG4CPLUS_ERROR("Bad string " << stringref(char_pointer, length));

應該管用。

字符串引用類的想法是保留有關字符串(大小和指針)的足夠信息,以引用代表字符串的任何內存塊。 它依賴於您確保底層字符串數據在stringref對象的整個生命周期內都有效。 這樣,您可以以最小的開銷傳遞並處理字符串信息。

當你知道它是固定長度的時候:為什么不簡單地再添加一個charakter到數組的大小? 然后你可以用\\ 0終止字符輕松填充最后一個字符,一切都會好的

不,你必須復制它。 您可以使用語言中的正確轉換來獲取數組類型。

你想要做到這一點似乎很奇怪,或者你首先有一個非終止的C風格的字符串。

你為什么不使用std::string

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM