Przepisanie string na string za pomocą pętli

0

Hejka to znowu ja;)

String można potraktować jak tablicę dynamiczną. Zatem wymyśliłem sobie że przepiszę string do stringa za pomocą pętli. Problem zaczyna być z tablicą wynikową. Odczytując litera po literze w pętli otrzymuję poprawny wynik. Ale wypisując na ekran już nic nie otrzymuję. Dlaczego? I pytanie bonusowe Ta operacja nie powoduje wycieku pamięci?

Pewnie jest jakaś inna łatwiejsza metoda zrobienia tego z jakąś nieznaną mi funkcją ale od razu zaznaczam że wolę pozostać przy tych bibliotekach/funkcjach żeby nie tłumaczyć się podczas zaliczenia z jakiś nieznanych mi elementów.

int dlugosc_adresu=adres2.length();
	string format;
	for(int i=dlugosc_adresu-4;i<dlugosc_adresu;i++){ 
		format[i-dlugosc_adresu+5]=adres2[i];
		cout<<format[i-dlugosc_adresu+5];
	}
	
	//test
	
	cout<<"dlugosc adresu="<<dlugosc_adresu<<"	format= "<<format;
	//test

P.S. Dlaczego w możliwych formatach załączników jest cpp a nie mogłem zamieścić programu inaczej niż spakowanego?

0

"Ta operacja nie powoduje wycieku pamięci?"
Piszesz po nie swojej pamięci. Oprócz tego, że pomysł przepisywania stringa w taki sposób jest średnio fajny, to możesz zrobić format.append(adres2[i]) zamiast format[i-dlugosc_adresu+5]=adres2[i];

0
pingwindyktator napisał(a):

"Ta operacja nie powoduje wycieku pamięci?"
Piszesz po nie swojej pamięci`

???

pingwindyktator napisał(a):

Oprócz tego, że pomysł przepisywania stringa w taki sposób jest średnio fajny, to możesz zrobić format.append(adres2[i]) zamiast format[i-dlugosc_adresu+5]=adres2[i];

Średnio fajny bo są lepsze metody czy średnio fajne bo nie działa to tak kolorowo jak by się wydawało? Nie poznawaliśmy tej metody (ani żadnej innej po za podstawowymi z fstream. Już naciągam trochę używając .lenght). Być może z niej skorzystam ale chciałbym też wiedzieć czemu ten fragment nie działa.

0

To jest typowy problem XY.
Wymyśliłeś jakieś dziwne rozwiązanie prostego problemu i prosisz o naprawienie dziwnego rozwiązania zamiast opisać co chcesz osiągnąć.

Najprawdopodobniej potrzebujesz std::ostringstream.

0

:p Pierwsze słyszę o tym problemie.
Z drugiej strony Always include information about a broader picture along with any attempted solution. Nie zawsze jest dobrym pomysłem bo zauważyłem że na wielu forach konieczność czytania ściany tekstów z wszelakimi wyjaśnieniami, skąd,dlaczego itd znacznie ogranicza możliwość otrzymania pomocy.

Wracając do tematu std::ostringstream Wydaje się być dużo ponad to co poznaliśmy więc na 90% nie wykorzystam.

Program ogólnie ma być prostym konsolowym programem do powiększania/obracania/wycinania obrazów. W wymaganiach mam podane między innymi odrzucanie innych rozszerzeń niż ppm i pgm i do tego właśnie służy problematyczny fragment. Podejrzewam że twórca miał na myśli obecność P2/P3 w nagłówku. Ale nie mając pewności muszę zaimplementować zarówno odpowiednie returny dla rozszerzeń == od wyżej wspomnianych jak i braku odpowiedniego nagłówku.

Na pierwszy ogień poszło rozszerzenie. Nie znałem żadnej funkcji ani metody jak coś takiego sprawdzić, a chcę (i chyba powinienem) wykorzystać tylko znane mi metody. Dlatego wymyśliłem że skoro podając nazwę pliku do edycji trzeba podać rozszerzenie to mogę wyciąć to rozszerzenie i wkleić do odpowiedniego ifa.

Wiedziałem że
a) string to tablica char
b) rozszerzenie jest zapisane w tym przypadku w 4/3 ostatnich znakach
Więc na podstawie tego stworzyłem

for(int i=dlugosc_adresu-4;i<dlugosc_adresu;i++){ 
		format[i-dlugosc_adresu+5]=adres2[i];
	}
if(format!=".pgm"&&format!=".ppm"){
		cout<<"Błędne rozszerzenie. Program działa tylko dla plików o rozszerzeniach .ppm i .pgm. Przerywam dzialanie programu.";
return 0;
	}

I teraz pozostało pytanie co w takiej implementacji sprawia że nie uzyskuję pożądanego efektu? Myślałem nad tym sam z 2 godziny, potem uznałem że albo coś przeoczyłem. Albo nie wiem o jakimś szczególe którego ciężko będzie wychwycić samodzielnie dlatego napisałem tutaj ;)

0

Masz nazwę pliku np "image.ppm"

Zrób na tej nazwie split (poszukaj string split w c++) - że rozdzielasz string na części np. kropką

wtedy masz
["test", "ppm"]

i sprawdzasz czy to co wyszło z tej tablicy na indexie ostatnim jest tym ppm lub pgm

@kq dlaczego nie trybi? :D

#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>

using namespace std;

vector<string> split(const string& s, char delimiter)
{
   vector<string> tokens;
   string token;
   istringstream tokenStream(s);
    
   while (getline(tokenStream, token, delimiter))
   {
      tokens.push_back(token);
   }
   return tokens;
}

int main()
{
    vector<string> allowedExtensions = {"ppm", "pgm"};
    string fileName = "test.ppm.xd";
    auto output = split(fileName, '.');
    
    if (find(allowedExtensions.begin(), allowedExtensions.end(), output[output.size()-1]) != allowedExtensions.end())
    {
        cout << "dobre rozszerzenie" << endl;
    }
    else
    {
        cout << "zle rozszerzenie" << endl;
    }
// zle rozszerzenie
}
1
auto index = fileName.rfind('.');
if (index == std::sring::npos) {
    cout << "Brak rozszeżenia\n";
    return;
}
auto ext = fileName.substr(index + 1);

if (ext != "ppm" && ext != "pgm") {
    cout << '"' << ext << "\" to błędne rozszerzenie. Program działa tylko dla plików o rozszerzeniach .ppm i .pgm.\n";
    return;
}
1
#include <iostream>
#include <set>
#include <experimental/filesystem>

using namespace std;

int main()
{
    set<string> allowedExtensions = {"ppm", "pgm"}; 
    string fileName = "test.ppm.xd";
    std::experimental::filesystem::path path(fileName);
    string fileExt = path.extension().string().substr(1);
    cout << ((allowedExtensions.count(fileExt)>0)?"dobre":"zle")<<" rozszerzenie\n";
}

Na Wandbox wymaga opcji kompilatora: "-lstdc++fs" (nie wiem jak tam się robi dobre skróty, nie mam konta).

0

chopy split stringa jest w boost :)

1

@shreder221: string to nie tablica charow. String jest obiektem. To jak jest zaimplementowany mało cię interesuje. To że pozwala korzystać jak z tablicy charow jest funkcjonalnością stringach.

Co musisz zrobić to zaalokowac pamięć dla tego stringach co stworzyłeś (bo jest teraz pusty więc kontener nie istnieje [powiedzmy])

Wtedy dopiero przepisuj

Nadal zgadzam się z poprzednikami że powinieneś uczyć się języka jako C++ a nie pisać C w C++ to już lepiej weź kurs do C

Długie posty są lepsze na 4p niż krótkie

1 użytkowników online, w tym zalogowanych: 0, gości: 1