web-gelistirme-sc.com

c ++ - Bir dizeye null atama

C++ 'ı kendi başıma öğreniyorum. Aşağıdaki kod var ama hata veriyor. 

#include <iostream>
#include <string>
using namespace std;


int setvalue(const char * value)
{
    string mValue;
    if(value!=0)
    {
       mValue=value;
    }
    else
    {
       mValue=0;
    }
}

int main ()
{
 const char* value = 0;
 setvalue(value);

 cin.get();
 return 0;
}

Bu yüzden karakter işaretlerini kabul eden bir fonksiyon yaratmak istiyorum ve ben ona bir işaretçi vermek istiyorum İşlev, işaretçiyi üye değişkenine atar. Bilerek boş bir işaretçi geçiyorum. Aşağıdaki alıyorum hatadır: 

 D:\CPP\TestCP.cpp In function `int setvalue(const char*)': 

 note C:\Dev-Cpp\include\c++\3.4.2\bits\basic_string.h:422 candidates are: std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>] 

 note C:\Dev-Cpp\include\c++\3.4.2\bits\basic_string.h:422                 std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const _CharT*) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>] 

 note C:\Dev-Cpp\include\c++\3.4.2\bits\basic_string.h:422                 std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(_CharT) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>] 

temelde hattan şikayet ediyor: mValue = 0;

Bu hattan neden şikayetçi? String'e boş değer atayamıyorum?

32
Maria

String'e boş değer atayamıyorum?

Hayır. std::string bir işaretçi türü değildir; "boş" yapılamaz. Bir değerin yokluğunu temsil edemez, bu da boş bir göstericinin temsil ettiği şeydir.

empty , boş bir dize atayarak (s = "" veya s = std::string()) veya temizleyerek (s.clear()) yapılabilir.

59
James McNellis

Nesne bir işaretçi olmadığı için NULL veya 0 işlevini C++ std::string nesnesine atayamazsınız. Bu C tarzı dizgilerden bir anahtar farktır; C stili bir dize NULL veya geçerli bir dize olabilir; oysa C++ std::strings her zaman bir değer depolar.

Bunun kolay bir çözümü yoktur. Nöbetçi bir değer ayırmak isterseniz (boş dize), gibi bir şey yapabilirsiniz.

const std::string NOT_A_STRING = "";

mValue = NOT_A_STRING;

Alternatif olarak, imleci null değerine ayarlamak için bir göstergeyi bir dizgiye kaydedebilirsiniz:

std::string* mValue = NULL;

if (value) {
    mValue = new std::string(value);
}

Bu yardımcı olur umarım!

13
templatetypedef

Değişmez 0int türündedir ve int öğesini std::string öğesine atayamazsınız. mValue.clear() kullanın veya boş bir dizge mValue="" atayın.

4
Juraj Blaho

Boş göstericileri C tarzı dizgilerde kullanmak için aynı etkiye sahip olan dikkate alınması gereken iki yöntem vardır.

Üçlü operatör

void setvalue(const char *value)
{
    std::string mValue = value ? value : "";

}

ya da alçakgönüllü if ifadesi

void setvalue(const char *value)
{
    std::string mValue;
    if(value) mValue = value;

}

Her iki durumda da, value, yalnızca mValue, değil boş bir işaretçi olduğunda value öğesine atanır. Diğer tüm durumlarda (yani, valueis null olduğunda), mValue boş bir dize içerecektir.

Üçlü işleç yöntemi, value öğesindeki bir değerin yokluğunda alternatif bir varsayılan dize değişmezi sağlamak için yararlı olabilir:

std::string mValue = value ? value : "(NULL)";
4
David Cormack

Bunun bir iyi bir fikir (ya da olmayan şeylerle nullptr kullanmanın anlambilimi) olduğunu iddia etmeyeceğim işaretçiler ), ancak " nullable " anlambilimi sağlayacak bir sınıf oluşturmak nispeten kolaydır (bkz nullable_string ).

Ancak, bu C++ 17'ler için çok daha uygun - std :: isteğe bağlı :

#include <string>
#include <iostream>
#include <optional>

// optional can be used as the return type of a factory that may fail
std::optional<std::string> create(bool b)
{
    if (b)
        return "Godzilla";
    else
        return {};
}

int main()
{
    std::cout << "create(false) returned "
              << create(false).value_or("empty") << std::endl;

    // optional-returning factory functions are usable as conditions of while and if
    if (auto str = create(true))
    {
        std::cout << "create(true) returned " << *str << std::endl;
    }
}

std::optional, örnekte gösterildiği gibi, bool öğesine dönüştürülebilir veya has_value() yöntemini kullanabilirsiniz, erişimin kötü olması için istisnalar vardır, vb. Olmak ne Maria başarmaya çalışıyordu.

C++ 17 uyumluluğu için beklemek istemiyorsanız, Boost.Optional hakkındaki bu cevaba bakın .

2
monkey0506

Çoğu C API, "varsayılanı kullan", örn. sivrisinek . İşte kullandığım kalıp, David Cormack 'ın cevabına göre:

    mosqpp::tls_set(
        MqttOptions->CAFile.length() > 0 ? MqttOptions->CAFile.c_str() : NULL,
        MqttOptions->CAPath.length() > 0 ? MqttOptions->CAPath.c_str() : NULL,
        MqttOptions->CertFile.length() > 0 ? MqttOptions->CertFile.c_str() : NULL,
        MqttOptions->KeyFile.length() > 0 ? MqttOptions->KeyFile.c_str() : NULL
    );

Bu biraz hantaldır, ancak API çağrılıncaya kadar her şeyi std::string olarak tutmaya izin verir.

0
Robert Calhoun

derleyici hata verir çünkü mValue = 0 derlenirken derleyici derleme zamanı bağlama için atama işlecini = (int) bulur ancak string sınıfında mevcut değildir. string sınıfı, operator = (char) yöntemini içerdiğinden başarıyla derlendi. 

0
Susheel Dwivedi

else durumu gereksizdir, string nesnesini oluşturduğunuzda varsayılan olarak boştur.

0
Naveen