Jak przekonwertować ciąg na tablicę znaków w C ++?

103

Chciałbym przekonwertować stringna chartablicę, ale nie char*. Wiem, jak przekonwertować ciąg na char*(używając malloclub w sposób, w jaki umieściłem go w moim kodzie) - ale nie tego chcę. Chcę po prostu przekonwertować stringna char[size]tablicę. Czy to możliwe?

#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;

int main()
{
    // char to string
    char tab[4];
    tab[0] = 'c';
    tab[1] = 'a';
    tab[2] = 't';
    tab[3] = '\0';
    string tmp(tab);
    cout << tmp << "\n";

    // string to char* - but thats not what I want

    char *c = const_cast<char*>(tmp.c_str());
    cout << c << "\n";

    //string to char
    char tab2[1024];
    // ?

    return 0;
}
Brian Brown
źródło
12
Wygląda na to, że jest to C ++, a nie C.
Fred Larson
@FredLarson: ok, zredagowano, dzięki
Brian Brown
3
możliwy duplikat std :: string do char *
cegprakash

Odpowiedzi:

123

Najprostszy sposób, w jaki mogę to zrobić, to:

string temp = "cat";
char tab2[1024];
strcpy(tab2, temp.c_str());

Ze względów bezpieczeństwa możesz preferować:

string temp = "cat";
char tab2[1024];
strncpy(tab2, temp.c_str(), sizeof(tab2));
tab2[sizeof(tab2) - 1] = 0;

lub może być w ten sposób:

string temp = "cat";
char * tab2 = new char [temp.length()+1];
strcpy (tab2, temp.c_str());
Chowlett
źródło
9
Haczyk strncpypolega na tym, że nie zakończy zerowania, jeśli osiągnie rozmiar przed znalezieniem wartości null w ciągu źródłowym. Z tym też trzeba być ostrożnym!
Fred Larson
1
Tak, myślę, że to rozsądny sposób radzenia sobie z tym.
Fred Larson
1
strncpy jest dla bezpieczeństwa, ponieważ strncpy nie przepełni bufora, który mu podasz. Również strcpy_s nie występuje w C99, ale został ostatnio dodany w C11.
bames53
6
Uwielbiam sposób, w jaki ludzie nadużywają słowa „ bezpieczeństwo” … och, nie ma wystarczająco dużo miejsca na sznurek, więc skróćmy go… och, przypadkowo usunęliśmy informację o alergii na leki zagrażającej życiu pacjenta… ale nie mamy bufor już się przepełnia. cóż, myślę, że to bezpieczne ...
Karoly Horvath
4
@KarolyHorvath - bezpieczeństwo w różnych dziedzinach. Oczywiście musisz sprawdzić swoje wymagania funkcjonalne i nie robić głupich rzeczy. Ale jeśli przekroczysz bufor, stracisz gwarancję, że wiesz, co się stanie. Prawidłowe kodowanie zapewnia „bezpieczne” działanie programu w systemie operacyjnym. Właściwe myślenie zapewnia, że ​​program jest „bezpieczny” w wykonywaniu tego, czego potrzebuje użytkownik.
Chowlett
58

Ok, jestem w szoku, że nikt tak naprawdę nie udzielił dobrej odpowiedzi, teraz moja kolej. Istnieją dwa przypadki;

  1. Tablica stała char jest wystarczająco dobre dla ciebie tak iść z,

    const char *array = tmp.c_str();
  2. Lub musisz zmodyfikować tablicę char, aby stała nie była w porządku, po prostu idź z tym

    char *array = &tmp[0];

Obaj są tylko operacje przypisania i przez większość czasu to jest właśnie to, czego potrzebujesz, jeśli naprawdę potrzebujesz nowej kopii, postępuj zgodnie z odpowiedziami innych kolegów.

rad
źródło
7
Chce tablicę
znaków
10
Utworzony przez niego wskaźnik jest tym samym, co tablica znaków. Zmienna tablicowa w C i C ++ jest po prostu wskaźnikiem do pierwszego elementu tablicy.
JustinCB
@ JustinC.B. nie całkiem! zmienne tablicowe mogą rozpadać się na wskaźniki, ale nie są takie same w C ++. np. std::size(elem)w C ++ jest dobrze zdefiniowane, kiedy elemjest a, char arrayale nie kompiluje się, gdy elemjest a char*lub const char*, możesz to zobaczyć tutaj
aniliitb10
16

Najłatwiej byłoby to zrobić w ten sposób

std::string myWord = "myWord";
char myArray[myWord.size()+1];//as 1 char space for null is also required
strcpy(myArray, myWord.c_str());
Społeczność
źródło
14
Rozmiar tablicy musi być stałą czasu kompilacji w C ++.
interjay
12
str.copy(cstr, str.length()+1); // since C++11
cstr[str.copy(cstr, str.length())] = '\0';  // before C++11
cstr[str.copy(cstr, sizeof(cstr)-1)] = '\0';  // before C++11 (safe)

Lepszą praktyką jest unikanie C w C ++, więc zamiast strcpy powinno być std :: string :: copy .

Youka
źródło
6

Po prostu skopiuj ciąg do tablicy za pomocą strcpy.

David Schwartz
źródło
5

Spróbuj w ten sposób, że powinno działać.

string line="hello world";
char * data = new char[line.size() + 1];
copy(line.begin(), line.end(), data);
data[line.size()] = '\0'; 
Tharindu Dhanushka
źródło
4

Spróbuj strcpy (), ale jak powiedział Fred, to jest C ++, a nie C

Marrow Gnawer
źródło
2

Możesz użyć strcpy(), na przykład:

strcpy(tab2, tmp.c_str());

Uważaj na przepełnienie bufora.

Fred Larson
źródło
2

Jeśli nie znasz wcześniej rozmiaru ciągu, możesz dynamicznie przydzielić tablicę:

auto tab2 = std::make_unique<char[]>(temp.size() + 1);
std::strcpy(tab2.get(), temp.c_str());
emlai
źródło
0

Cóż, wiem, że to może raczej głupie niż i proste, ale myślę, że powinno działać:

string n;
cin>> n;
char b[200];
for (int i = 0; i < sizeof(n); i++)
{
    b[i] = n[i];
    cout<< b[i]<< " ";
}
SquircKle
źródło
No nie bardzo. Zakładasz tylko, że nto nie może być większe niż b. Jeśli n>b. Lepiej jest skorzystać z strcpyjuż udostępnionej funkcji. Edycja: W niektórych przypadkach może być jeszcze lepiej, strcpy_sponieważ dodaje sprawdzanie wskaźników NULL (jeśli twoja platforma je obsługuje)
droidballoon
0

Jeśli używasz C ++ 11 lub nowszego, sugerowałbym użycie std::snprintfover std::strcpylub std::strncpyze względu na jego bezpieczeństwo (tj. Określasz, ile znaków można zapisać w twoim buforze) i ponieważ kończy on ciąg znaków za Ciebie (więc nie musisz się tym martwić). Byłoby tak:

#include <string>
#include <cstdio>

std::string tmp = "cat";
char tab2[1024];
std::snprintf(tab2, sizeof(tab2), "%s", tmp.c_str());

W C ++ 17 masz taką alternatywę:

#include <string>
#include <cstdio>
#include <iterator>

std::string tmp = "cat";
char tab2[1024];
std::snprintf(tab2, std::size(tab2), "%s", tmp.c_str());
luizfls
źródło