[C++]Zamieszanie ze stringami typu char*

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
macer
Wytworny Kaczor
Wytworny Kaczor
Posty: 453
Rejestracja: 12 wrz 2009, 21:07
Wersja Ubuntu: inny OS

[C++]Zamieszanie ze stringami typu char*

Post autor: macer »

Zacząłem przepisywać pewien algorytm z php, narazie mam tyle:

Kod: Zaznacz cały

#include <iostream>
#include <gd.h>
#include <cstring>
#include <cstdlib>
using namespace std;
int main(int argc,char* argv[])
{	
	FILE *in = fopen("plik.jpg","r");
	FILE *out = fopen("zakodowany.png","w");
	gdImagePtr image = gdImageCreateFromJpeg(in);

	char* tekst = "Hello coding world :-)";
	cout << strlen(tekst);
	
	
}
Problem w tym że przy uruchamianiu programu dostaję "Segmation fault".
Myślę że to przez to że jakoś źle deklaruje "tekst", może trzeba dodać "const", czy jeszcze coś innego.
Wie ktoś co na to poradzić?

PS nie mogę zadeklarować jako "string" bo wtedy nie działa "strlen(tekst)".
pantich
Piegowaty Guziec
Piegowaty Guziec
Posty: 17
Rejestracja: 06 lut 2007, 17:22
Płeć: Mężczyzna
Wersja Ubuntu: 11.04
Środowisko graficzne: GNOME
Architektura: x86_64
Kontakt:

Odp: [C++]Zamieszanie ze stringami typu char*

Post autor: pantich »

PS nie mogę zadeklarować jako "string" bo wtedy nie działa "strlen(tekst)".
zamiast strlen możesz użyć metody size
Pozdro dla przyjaciół mojej zdechłej morskiej pszczoły...
Awatar użytkownika
thalcave
Przyjaciel
Przyjaciel
Posty: 821
Rejestracja: 08 lis 2006, 12:17
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Fluxbox
Architektura: x86

Odp: [C++]Zamieszanie ze stringami typu char*

Post autor: thalcave »

Kod: Zaznacz cały

string text = "To jest moj tekst";

    cout << text.length() << endl;
działa - Pamiętaj stroing to klasa a nie typ zmiennej.

Poza tym w C++ wczytywanie/zapis do pliku odbywa się tak (tak mnie przynajmniej uczono) - szybciej de facto:

Kod: Zaznacz cały

#include <fstream>
[...]
ifstream in("plik_do_wczytania);
ofstream out("plikdozapisu");

string text;
in >> text;

out << text;
GNU/Linux user
Na pytania na PW/e-mail nie udzielam odpowiedzi!
Szanujmy innych użytkowników!
Wesprzyj akcje: Temat rozwiązany -> dodajemy [solved]
Awatar użytkownika
beluosus
Zakręcona Traszka
Zakręcona Traszka
Posty: 695
Rejestracja: 01 paź 2006, 15:32
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86
Kontakt:

Odp: [C++]Zamieszanie ze stringami typu char*

Post autor: beluosus »

Eh... http://www.cplusplus.com/reference/stri ... ng/length/
i
http://www.cplusplus.com/reference/clib ... ng/strlen/
Jak widzisz, strlen jest dla C-stringów, a string ma swoją metodę.
Kurs Linuksa: for i in $(ls /bin); do man $i; done
__________________
http://beluosus.pl/
Awatar użytkownika
el.pescado
Zakręcona Traszka
Zakręcona Traszka
Posty: 734
Rejestracja: 26 maja 2005, 11:43
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: GNOME
Architektura: x86
Kontakt:

Odp: [C++]Zamieszanie ze stringami typu char*

Post autor: el.pescado »

Kod: Zaznacz cały

$ g++ -g -Wall -o program program.cpp
$ gdb ./program
(gdb) run
i patrzysz gdzie program dokładnie się wysypuje...
luzakwielki
Wytworny Kaczor
Wytworny Kaczor
Posty: 264
Rejestracja: 19 lis 2008, 11:42
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: KDE Plasma
Architektura: x86_64

Odp: [C++]Zamieszanie ze stringami typu char*

Post autor: luzakwielki »

macer pisze:Zacząłem przepisywać pewien algorytm z php, narazie mam tyle:

Kod: Zaznacz cały

#include <iostream>
#include <gd.h>
#include <cstring>
#include <cstdlib>
using namespace std;
int main(int argc,char* argv[])
{	
	FILE *in = fopen("plik.jpg","r");
	FILE *out = fopen("zakodowany.png","w");
	gdImagePtr image = gdImageCreateFromJpeg(in);

	char* tekst = "Hello coding world :-)";
	cout << strlen(tekst);
	
	
}
Problem w tym że przy uruchamianiu programu dostaję "Segmation fault".
Myślę że to przez to że jakoś źle deklaruje "tekst", może trzeba dodać "const", czy jeszcze coś innego.
Wie ktoś co na to poradzić?

PS nie mogę zadeklarować jako "string" bo wtedy nie działa "strlen(tekst)".
const char* wyrzuci Ci tylko ostrzeżenie z logów, ale problemu nie załatwi, bo to nie o to chodzi.
Błąd tu polega na tym, że plik.jpg nie istnieje, i się nie otworzył, a chcesz z niego czytać gdImageCreateFromJpeg (z pustego i Salomon nie naleje ;p). Następnym razem sprawdzaj czy plik który otwierasz istnieje:

Kod: Zaznacz cały

if(!in){printf("plik nie istnieje"); exit(0);}
else{
//wszystko ok można czytać z pliku
}

EDIT:
thalcave pisze:

Kod: Zaznacz cały

string text = "To jest moj tekst";

    cout << text.length() << endl;
działa - Pamiętaj stroing to klasa a nie typ zmiennej.

Poza tym w C++ wczytywanie/zapis do pliku odbywa się tak (tak mnie przynajmniej uczono) - szybciej de facto:
Działa - tylko po co w tym wypadku korzystać z std::string, skoro zupełnie nie w tym tkwi problem?

Czyli nie nauczono Cię, że C++ zawiera w sobie C, a funkcje, które pokazałeś spowalniają bardzo odczyt/zapis (jest stosowana synchronizacja) - można niby zmniejszyć różnicę przez wyłączenie synchronizacji wejścia/wyjścia (ios_base::sync_with_stdio(0);), ale dalej wydajność jest niższa niż w przypadku odpowiedników z C.
Swoją drogą nie da się użyć strumieni C++ w tym wypadku, bo biblioteka GD jest pisana w C i użyta funkcja wymaga uchwytu do pliku (FILE*)
macer
Wytworny Kaczor
Wytworny Kaczor
Posty: 453
Rejestracja: 12 wrz 2009, 21:07
Wersja Ubuntu: inny OS

Odp: [C++]Zamieszanie ze stringami typu char*

Post autor: macer »

Normalnie to bym skorzyształ z ifstream/ofstream, ale gd wymaga użycia FILE*.
Dzięki za rady, mogę pisać dalej ;-)

EDIT:
el.pescado: dzięki za podpowiedź z debugerem, napewno mi się to kiedyś przyda ;-)

EDIT:
el.pescado, czemu dałeś opcja -g przy kompilowaniu?
luzakwielki
Wytworny Kaczor
Wytworny Kaczor
Posty: 264
Rejestracja: 19 lis 2008, 11:42
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: KDE Plasma
Architektura: x86_64

Odp: [C++]Zamieszanie ze stringami typu char*

Post autor: luzakwielki »

macer pisze:el.pescado, czemu dałeś opcja -g przy kompilowaniu?
Żeby binarka zawierała informacje dla debuggera.
mikolajs
Wytworny Kaczor
Wytworny Kaczor
Posty: 352
Rejestracja: 15 paź 2008, 18:30
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: KDE Plasma

Odp: [C++]Zamieszanie ze stringami typu char*

Post autor: mikolajs »

Kod: Zaznacz cały

char* tekst = "Hello coding world :-)";
	cout << strlen(tekst);
Czyli nie nauczono Cię, że C++ zawiera w sobie C, a funkcje, które pokazałeś spowalniają bardzo odczyt/zapis (jest stosowana synchronizacja) - można niby zmniejszyć różnicę przez wyłączenie synchronizacji wejścia/wyjścia (ios_base::sync_with_stdio(0), ale dalej wydajność jest niższa niż w przypadku odpowiedników z C.
W większości przypadków to prawda. Tutaj jednak mamy strlen(), który musi policzyć ilość znaków w c stringu, podczas gdy string w momencie tworzenia zapisuje wartość ilości znaków (pewnie więc wychodzi na to samo :) ). Warto korzystać z udogodnień języka C++ w stosuku do C, a bezpośrednio z funkcji C korzystać w wyjątkowych wypadkach.
Jeżeli potrzebny jest c string to string ma metodę c_str().
macer
Wytworny Kaczor
Wytworny Kaczor
Posty: 453
Rejestracja: 12 wrz 2009, 21:07
Wersja Ubuntu: inny OS

Odp: [C++]Zamieszanie ze stringami typu char*

Post autor: macer »

@luzakwielki: o co ci chodziło z tą synchronizacją w pliku?
Awatar użytkownika
el.pescado
Zakręcona Traszka
Zakręcona Traszka
Posty: 734
Rejestracja: 26 maja 2005, 11:43
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: GNOME
Architektura: x86
Kontakt:

Odp: [C++]Zamieszanie ze stringami typu char*

Post autor: el.pescado »

luzakwielki
Wytworny Kaczor
Wytworny Kaczor
Posty: 264
Rejestracja: 19 lis 2008, 11:42
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: KDE Plasma
Architektura: x86_64

Odp: [C++]Zamieszanie ze stringami typu char*

Post autor: luzakwielki »

macer pisze:@luzakwielki: o co ci chodziło z tą synchronizacją w pliku?
Wyjście/wejście w C++ ma standardowo włączoną synchronizacje.
mikolajs pisze:W większości przypadków to prawda. Tutaj jednak mamy strlen(), który musi policzyć ilość znaków w c stringu, podczas gdy string w momencie tworzenia zapisuje wartość ilości znaków (pewnie więc wychodzi na to samo :) ). Warto korzystać z udogodnień języka C++ w stosuku do C, a bezpośrednio z funkcji C korzystać w wyjątkowych wypadkach.
Jeżeli potrzebny jest c string to string ma metodę c_str().
Tak strlen wymaga przejścia przez tablice w poszukiwaniu pierwszego zera - co nie znaczy, że sobie nie możesz opakować w klasę c string i zapisywać potrzebne Ci informacje w konstruktorze.
Zgadzam się, że warto wykorzystywać zalety języka C++, ale jeśli potrzebujesz c string lepiej użyć tablicy znaków niż std::string::c_str(), bo jak pewnie dobrze wiesz, że w string nie jest przechowywany c string tylko osobno znaki, nie po kolei (każda litera ma wskaźnik na kolejną w kolejce) i musi zaalokować pamięć na nowego c stringa, i przepisać wszystko po jednej literce.
Awatar użytkownika
el.pescado
Zakręcona Traszka
Zakręcona Traszka
Posty: 734
Rejestracja: 26 maja 2005, 11:43
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: GNOME
Architektura: x86
Kontakt:

Odp: [C++]Zamieszanie ze stringami typu char*

Post autor: el.pescado »

Zgadzam się, że warto wykorzystywać zalety języka C++, ale jeśli potrzebujesz c string lepiej użyć tablicy znaków niż std::string::c_str(), bo jak pewnie dobrze wiesz, że w string nie jest przechowywany c string tylko osobno znaki, nie po kolei (każda litera ma wskaźnik na kolejną w kolejce) i musi zaalokować pamięć na nowego c stringa, i przepisać wszystko po jednej literce.
Nie, std::string nie jest zaimplementowany jako lista wiązana. Obiekty tej klasy zawierają wskaźnik do tablicy znakowej. Zresztą, wystarczy zobaczyć sobie w źródłach:
/usr/include/c++/4.3.3/bits/basic_string.h:

Kod: Zaznacz cały

	_CharT* _M_p; // The actual data.
Tak więc, std::string wewnętrznie wykorzystuje tablicę znakową, a metoda c_str() po prostu zwraca wskaźnik do tej tablicy.
luzakwielki
Wytworny Kaczor
Wytworny Kaczor
Posty: 264
Rejestracja: 19 lis 2008, 11:42
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: KDE Plasma
Architektura: x86_64

Odp: [C++]Zamieszanie ze stringami typu char*

Post autor: luzakwielki »

el.pescado pisze:Nie, std::string nie jest zaimplementowany jako lista wiązana. Obiekty tej klasy zawierają wskaźnik do tablicy znakowej. Zresztą, wystarczy zobaczyć sobie w źródłach:
/usr/include/c++/4.3.3/bits/basic_string.h:

Kod: Zaznacz cały

	_CharT* _M_p; // The actual data.
Tak więc, std::string wewnętrznie wykorzystuje tablicę znakową, a metoda c_str() po prostu zwraca wskaźnik do tej tablicy.
Tak tablica znaków jest - z tym, że nie są w kolejności jaka jest potrzebna... C string "tekst", w tablicy znaków w stringu może wyglądać tak "sektt", a osobno jest przechowywana lista ze wskaźnikiem do konkretnego chara i wskaźnikiem na kolejny element.
Awatar użytkownika
el.pescado
Zakręcona Traszka
Zakręcona Traszka
Posty: 734
Rejestracja: 26 maja 2005, 11:43
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: GNOME
Architektura: x86
Kontakt:

Odp: [C++]Zamieszanie ze stringami typu char*

Post autor: el.pescado »

Nie wiem czemu to miałoby służyć taka implementacja - a zajmowałaby od 9 do 17 razy więcej miejsca, zależnie od architektury.

std::string zawiera najzwyklejszą tablicę znaków. wystarczy spojrzeć na metodą c_str():

Kod: Zaznacz cały

      _CharT*
      _M_data() const
      { return  _M_dataplus._M_p; }

      const _CharT*
      c_str() const
      { return _M_data(); }
mikolajs
Wytworny Kaczor
Wytworny Kaczor
Posty: 352
Rejestracja: 15 paź 2008, 18:30
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: KDE Plasma

Odp: [C++]Zamieszanie ze stringami typu char*

Post autor: mikolajs »

Zgadzam się, że warto wykorzystywać zalety języka C++, ale jeśli potrzebujesz c string lepiej użyć tablicy znaków niż std::string::c_str(), bo jak pewnie dobrze wiesz, że w string nie jest przechowywany c string tylko osobno znaki, nie po kolei (każda litera ma wskaźnik na kolejną w kolejce) i musi zaalokować pamięć na nowego c stringa, i przepisać wszystko po jednej literce.
Klasa string jest stworzona do manipulacji. Jeżeli chcesz zmieniać string to jest to warto jej użyć, jeżeli tylko chcesz przekazać napis do metody to wystarczy const char*
Co prawda w wielu językach (Java, Scala, Python) stringi faktycznie opierają się na stałych napisach znakowych i nie stosuje się kontenera, ale nie opłaca się tego samodzielnie pisać w C++, wygodniej jest używać kontenerów.
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Amazon [Bot] i 3 gości