Witam
Moj problem polega na tym ze nie moge sobie poradzic z konwersja System:string na std::str w vc++ jak w temacie. Obecnie jak juz wspomnialem uzywam vc++ i mam problem z odczytaniem wybranego pliku np txt.
uzywajac fstream w ktorym wpisuje sie lokalizacje pliku uzywamy std::string a openFileDialog uzywa System::String i przez to nie moge skompilowac programu.
Jak bedzie potrzeba moge dac kod programu. Oczywiscie zanim tutaj napisalem szukalem informacji na google jednak nic skutecznego nie znalazlem. przykladowy link http://msdn.microsoft.com/en-us/library/ms235631(VS.80).aspx jednak vc nawet takich plikow naglowkowych nie ma ktore tam sa podane i mysle ze istnieje latwiejszy sposob rozwiazania problemu moze nie koniecznie do odczytu pliku uzywac fstream tylko co? prosze o pomoc w tej sprawie.
Zalozylem nowy temat mimo iz istnieje jednak z roku 2004 co za tym idzie nie ma konretnej odpowiedzi o ktora mi chodzi.
Dzieki za wszystkie odpowiedzi i pomoc w tej sprawie.
nie jestem pewien czy dobrze zrozumiałem istotę problemu (na wszelki wypadek wklej kawałek kodu, gdzie tkwi problem)... ale... po co uzywac fstream, kiedy mozna uzyc np. klasy StreamReader (System::IO)
O to moj kod
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
//-------------------------------------
using namespace std;
fstream plik;
openFileDialog1->InitialDirectory = "c:\ ";
openFileDialog1->Filter = "csv files (*.csv)|*.csv|All files (*.*)|*.*";
openFileDialog1->FilterIndex = 1;
if ( openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK )
{
System::String ^tekst = "tekst testowy";
string tekstkonw = ^tekst::basic_fstream::eof;
plik.open(openFileDialog1->FileName,std::ios::in);
if(plik.good()==true)
{
//tu operacje na pliku
string dane;
while(!plik.eof())
{
getline(plik,dane);//wczytanie CAŁEGO jednego wiersza danych
//------------tworzenie tablicy z funkcji ktora zwraca tablice
if (plik.eof()) { //petla robi sie o jedna za duzo z tad ten warunek
break;
}
char w;
w=59;
string *wsk ;
string array[5];
int i;
wsk=Explode(dane,w);
array[0] = *wsk;
array[1] = *(wsk+1);
array[2] = *(wsk+2);
array[3] = *(wsk+3);
array[4] = *(wsk+5);
Oczywiscie na koncu sa klamry to nie caly kod najlepiej bym mogl konwertowac na std::string gdyz jeszcze napisaelm sobie funkcje ktora rozdziela tresc ze stringa na tablice
Jak pisalem taki sam program w borlanndzie to wystarczylo dopisac do zmiennej c_str(); gdyz tam byl konwert z AnsiString do string
plik.open(openFileDialog1->FileName,std::ios::in);
tutaj wyskakuje blad konwersji
Użyj .NETowych klas do obsługi plików - np. StreamReader z System::IO - nie będzie takich problemów.
Czy moglbys pokazac przykladowe zastosowanie tego?
Gdyz ja nauczylem sie i dalej sobie utwalam c++ z konsoli a z vc++ niestety raczkuje a ten projekt musze koniecznie napisac. Zamowilem sobie juz jakies ksiazki jednak nie wiem kiedy dojada ma byc dostawa w ciagu 7 dni jednak nie moge za bardzo czekac na nie. vc++ mi sie bardzo spodobal jednak wiele nauki przede mna:)
using namespace System::IO;
....
Stream^ myStream;
OpenFileDialog^ open = gcnew OpenFileDialog;
open->Filter = "BBO Compatible LIN file|*.lin";
open->FilterIndex = 1;
open->RestoreDirectory = true;
open->Title = "Open *.lin file";
open->InitialDirectory = Application::StartupPath;
if ( open->ShowDialog() == Windows::Forms::DialogResult::OK )
{
if ( (myStream = open->OpenFile()) != nullptr )
{
StreamReader^ sw = gcnew StreamReader(myStream);
textBox->Text = sw->ReadToEnd(); //to jedna z mozliwosci, tutaj zapisuje zawartosc pliku do textBoxa
sw->Close();
}
}
myStream->Close();
Po dodaniu textBox-a zmiany nazwy na "textBox" wyskakuja bledy kompilacji
<debuger>
1>c:\users\góra\documents\visual studio 2008\projects\goravc\goravc\Form1.h(391) : error C2065: 'RestoreDirectory' : undeclared identifier
1>c:\users\góra\documents\visual studio 2008\projects\goravc\goravc\Form1.h(399) : error C2039: 'ReadtoEnd' : is not a member of 'System::StreamReader'
</debuger>
przepraszam, przerabialem to z wlasnego kodu (gdzie uzywalem SaveFileDialog) i przeoczylem literowki :)
1)przed RestoreDirectory oczywiscie wskaznik "->"
2)ReadToEnd() - rowniez literowka
Sprobuj teraz (poprawie tez tutaj)
chodzi o to, ze RestoreDirectory() (jesli jest ustawiona na true) przywraca (przy zamknieciu dialogu) aktualna sciezke sprzed jego otwarcia)
jak zauwazyles w kodzie wystepuje linia
open->InitialDirectory = Application::StartupPath;
, a wiec flaga RestoreDirectory jest zbyteczna :P (sorki, tez jestem w trakcie nauki)
Jak juz skompilujesz ten fragment kodu pomyslnie, zauwazysz tez pewnie, ze po wcisnieciu "ANULUJ" w oknie dialogowym wyskoczy błąd ... chodzi o null reference (musisz obsluzyc ten wyjatek, ale zostawiam to juz Tobie)
Programik sie kompiluje juz, bardzo fajnie ale jeszcze nie wczytuje pliku pewnie jakis blad zrobilem zaraz postaram sie obadac sprawe.......
Docelowo i tak musze to wczytac do listview.
dziekuje za pomoc:) jeszcze sporo nauki mnie czeka juz nie moge sie doczekac tych ksiazek o ktorych wspomnialem wyzej:)
zmien tam sobie rodzaj pliku na txt (w kodzie jest lin - to na potrzeby mojej aplikacji)
btw, jakie książki zamowiles? bo ja aktualnie czytam "beginning visual c++" Hortona i .NET 3.5 C++/CLI wydawnictwa APRESS
Pliczek juz mi sie zaczytuje ale teraz mam problem z funkcja ;/ ktora mi zwraca z ciagu striinga tablice
funkcja byla pod std::string a nie System::string prosze o pomoc by zwracala System::String i by przekazane byly argumenty tez w tym typie albo moze faktycznie bedzie latwiej przekonwertowac std::string do System::String tylko jak
o to kod funkcji:
std::string* Explode(string& str,char delimeter) {
if(str.empty() == true) return NULL;
unsigned len = str.size();
unsigned liczba_wystapien = 0;
for(unsigned i = 0; i<len;++i) {
if(str[i] == delimeter) ++liczba_wystapien;
};
std::string* wynik = new std::string [++liczba_wystapien];
unsigned licznik = 0;
int x = 0;
int pozDelimeter;
//unsigned pozDelimeter;
for(int licznik = 0; x <= len; ++licznik) {
pozDelimeter = str.find(delimeter,x);
if(pozDelimeter == -1) pozDelimeter = len;
std::string substr = str.substr(x,(pozDelimeter-x));
wynik[licznik] = substr;
x = ++pozDelimeter;
};
return wynik;
}
Rodzaj Pliku sobie zmienilem na CSV gdyz taki mi potrzebny, a co do ksiazek to sobie zamowilem z heliona
++. Wykorzystaj potęgę aplikacji graficznych,
C++Builder 6 i bazy danych
C# 2005. Warsztat programisty
Hmm... Ty czasem nie wynajdujesz koła na nowo? Przecież do dzielenia stringa służy metoda Split:
String^ napis = "Ala ma kota i psa";
array<String^>^ slowa = napis->Split(' ');
for(int i = 0; i<slowa->Length; i++)
Console::WriteLine(slowa[i]);
Tak tylko ja sobie zrobilem tak by separatorem bylo to co sobie wpisze do char co mi ulatwia sprawe. Ale przyznam sie ze nie znalem tej motody...
No a tutaj też możesz sobie wpisać nie tylko dowolnego chara, ale także wrzucić ich tablicę, np:
String^ napis = "Ala.ma,kota:i;psa";
array<String^>^ slowa = napis->Split(',','.',';',':');
for(int i = 0; i<slowa->Length; i++)
Console::WriteLine(slowa[i]);
Faktycznie dziekuje za podpowiedz teraz to juz mam zrobione tak jak chcialem jak ktos jest Ciekawy moge pokazac kod:)
Pokaż ten kod, może okaże się, że jeszcze kilka innych kół wynalazłeś niepotrzebnie ;)
O to kod:)
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
//-------------------------------------
using namespace System::IO;
Stream^ myStream;
OpenFileDialog^ open = gcnew OpenFileDialog;
open->Filter = "CSV file|*.csv";
open->FilterIndex = 1;
//open->RestoreDirectory = true;
open->Title = "Open *.CSV file";
//open->InitialDirectory = Application::StartupPath;
open->InitialDirectory = "e:\ ";
if ( open->ShowDialog() == Windows::Forms::DialogResult::OK )
{
if ( (myStream = open->OpenFile()) != nullptr )
{
StreamReader^ sw = gcnew StreamReader(myStream);
//----wydzielenie slow
while ( sw->EndOfStream == false )
{
String^ napis = sw->ReadLine();
array<String^>^ slowa = napis->Split(';');
for(int i = 0; i<slowa->Length; i++)
Console::WriteLine(slowa[i]);
//-wydzielenie slow
ListViewItem^ item1 = gcnew ListViewItem( slowa[0],0 );
item1->Checked = true;
item1->SubItems->Add( slowa[1] );
item1->SubItems->Add( slowa[2] );
item1->SubItems->Add( slowa[3] );
item1->SubItems->Add( slowa[5] );
array<ListViewItem^>^temp1 = {item1};
lista->Items->AddRange( temp1 );
}
sw->Close();
}
}
myStream->Close();
//-------------------------------------
}
Można i tak:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
//zaczynamy na pulpicie
this->openFileDialog1->InitialDirectory = Environment::GetFolderPath(Environment::SpecialFolder::DesktopDirectory);
//jeśli użytkownik wybrał plik
if(this->openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK)
{
//wczytanie wszystkich linii z pliku na raz
array<String^>^ linie = File::ReadAllLines(this->openFileDialog1->FileName);
//przetworzenie każdej linii
for(int i = 0; i < linie->Length; i++)
{
//podzielenie linii
array<String^>^ slowa = linie[i]->Split(';');
//utworzenie ListViewItem, dodanie do niego SubItem'ów i dodanie do ListView
ListViewItem^ item = gcnew ListViewItem(slowa[0]);
item->Checked = true;
item->SubItems->AddRange(gcnew array<String^> { slowa[1], slowa[2], slowa[3], slowa[5] });
this->listView1->Items->Add(item);
}
}
}