2009-10-15 18 views
10

C'è qualcosa di simile in Standard C++/STL? Idealmente dovrebbe essere costruito comeClasse di lunghezza fissa C++?

fstring s = fstring(10); 

Ho bisogno di costruire a volte o avere una stringa di dimensioni fisse. A volte per essere in grado di leggere/scrivere solo molti caratteri in un flusso.

Edit:

Nota che la dimensione è nota solo in fase di esecuzione, ed è diverso da uno all'altro. Ma tutti i fstring s dovrebbero sapere come lavorare insieme e avere tutto il fantastico comportamento string.

+1

Sono un po 'arrugginito, ma come si differenzia da un carattere []? – Lazarus

+1

@Lazarus: una classe std :: string-esque fixed-string potrebbe offrire molte più funzionalità, tra cui l'override di <>, rispetto al tipo char [] di base. È anche possibile che AFAIK non abbia std :: vector , ma sarebbe possibile avere std :: vector >. – Tom

+0

Che comportamento di stringa "di fantasia" vuoi usare? Ci aiuterebbe a fornire una risposta migliore se conoscessimo il sottoinsieme delle funzioni membro della stringa che stavate utilizzando. –

risposta

0

Serie di caratteri stile C?

char label[10] = "a string"; 
+0

Mancano tutte le funzioni membro di un container STL, anche il sottoinsieme che potrebbe essere applicato a un contenitore a lunghezza fissa. – sbi

1

Perché non utilizzare std :: basic_string da STL come classe di stringa fissa?

È possibile utilizzare il costruttore

basic_string(
    size_type _Count, 
    value_type _Ch, 
    const allocator_type& _Al = Allocator () 
); 

come inizializzazione.

Successivamente modificare: Esempio:

std::string my10CharStringInitializedWithSpace(10, ' '); 
+0

Il problema è che la stringa creata non esegue alcun taglio/riempimento o garantisce il suo limite di 10 caratteri. – Ayman

+0

Per questo, è necessario definire la propria classe, se si desidera una soluzione incapsulata, o utilizzare ciò che esiste sul mercato. Vedi gli algoritmi boost string per il trimming: http://www.boost.org/doc/libs/1_40_0/doc/html/string_algo.html –

0

Se ho capito bene, non si vuole usare std::string perché siete preoccupati che potrebbe silenziosamente espandere su di voi. Vedo un paio di opzioni:

  1. utilizzare una stringa C-stile crudo e le funzioni da cstdio che prendere un argomento di lunghezza (per esempio, fgets).

  2. Utilizzare un std::vector<char>.

+0

Ma 'std :: vector ' si espanderà silenziosamente anche tu! Prendi http://stackoverflow.com/questions/1571901/1571978#1571978 – sbi

+0

Solo se lo chiedi. 'operator >>' su una stringa espanderà automagicamente la stringa per adattarsi a qualsiasi cosa tu stia leggendo. Con un vettore dovresti inserire o spingere esplicitamente il limite imposto. –

+0

Ah, ti riferisci a 'operator >>'. Questo non era chiaro dal tuo post. – sbi

1

C'è probabilmente qualcosa in spinta che fornisce questo (la più vicina Ho visto personalmente è Boost.Array, che è insufficiente). Tuttavia, se si sta solo cercando di modellare il "importante sottoinsieme" di std::string, non è molto difficile fare una lunghezza fissa equivalente:

template <size_t N> 
class fixed_string 
{ 
    // ... interface looks like std::string 
}; 

Per chiunque chiedendo il motivo per preoccuparsi di fare questo a tutti, il Il vantaggio principale è evitare l'allocazione della memoria senza perdere gran parte dell'utile API std::string. Se c'è un altro modo per farlo con std::allocator, sarei curioso di sapere.

+0

Ho provato, ma non vedo come questo possa funzionare. Il problema è che la stringa potrebbe richiedere più memoria dall'allocatore di quanto ne abbia bisogno al momento. Ad esempio, quando ho impostato il limite del mio allocatore su 32 caratteri, sono riuscito a respingere solo 16 caratteri su 25. – UncleBens

10

l'approssimazione più vicina oggi è boost::array<char, 10>

5

Usa per esempio

std::tr1::array<char, 10> 
+5

Ora che C++ 11 è qui da un po ', si può usare std :: array a http://en.cppreference.com/w/cpp/container/array. –

2

ne dite di ereditare std::string privatamente quindi esporre un'interfaccia più piccolo con using, e scrivere i propri < < e >> funzioni?

1

Ho usato qualcosa di simile per le stringhe allocate nello stack o come parte di un altro oggetto. Che in versione diventa un char *

#ifdef DEBUG 
#define STR_DEBUG 
#endif 

#define FIXED_STRING(maxSize) ReservedString<maxSize> _Tmp##__LINE__; 

class FixedString{ 
public: 
    FixedString& operator =(char const * const pStr); 
    //FixedString& operator =(FixedString const &pStr); 
    operator const char*() const { return mStr; } 
    const char* cStr() const { return mStr; } 
    FixedString& operator +=(const char *pStr); 
    bool equals(const char *pStr); 
    bool beginsWith(const char *pStr); 
    /// rises ASSERT if not enough 
    void ensureEnoughForNMore(int NMoreSymbols); 
protected: 
    char *mStr; 
    #ifdef STR_DEBUG 
     ui16 mMaxLength; 
    #endif 

private: 
    #ifdef STR_DEBUG 
     FixedString(char *str, ui16 maxLength): mStr(str), mMaxLength(maxLength) {} 
    #else 
     FixedString(char *str): mStr(str) {} 
    #endif 
    template<int> 
    friend class ReservedString; 
}; 

template <int MAX_LENGTH> class ReservedString{ 
public: 
    operator FixedString() { 
     #ifdef STR_DEBUG 
      return FixedString(mBuf, MAX_LENGTH); 
     #else 
      return FixedString(mBuf); 
     #endif 
    } 
private: 
    char mBuf[MAX_LENGTH+1]; 
}; 
1

Con C++ 11, si può andare per

std::array<char,10> s; 

anche std :: string equivalente può sempre essere costruito, in caso di necessità

std::string s2(std::begin(s), std::end(s)); 
Problemi correlati