Witam, mam problem, mianowicie
Potrzebuję w programie zrobić odczyt z pliku csv, ten plik (wyrazy bez spacji i przecinków) musi zostać przerobiony na tablice stringów którą później będzie losował (wybierał jeden wyraz) i wyświetlał w labelu
Jedyne co to wiem, że odczytać plik mogę tym tresc = File.ReadAllLines(textBox1.Text, Encoding.Unicode);
i ze to zapisze mi to w tablicy stringów, tylko czy to będą wszystkie wyrazy w jednym elemencie, czy każdy z osobna ?
Z góry dziękuje za odpowiedź, i przepraszam za prawdopodobnie głupie pytania.
Widzę, że nikt nie odpowiada, to rzucę swoje 3 grosze (najlepiej gdyby ktoś sprawdził/poprawił, czy ma to sens)
Jeżeli interesuje cię rozwiązanie ze ścieżką do pliku, to:
Mamy plik:
I chcemy uzyskać taki efekt
To tutaj przykładowy kod:
StringBuilder csv_in_one_line = new StringBuilder();
string path = @"C:\sample-csv.csv";
var fileLines = File.ReadAllLines(path);
foreach (var singleLine in fileLines)
{
csv_in_one_line.Append(singleLine);
csv_in_one_line.Append(',');
}
string dane = Convert.ToString(csv_in_one_line);
string[] tablica = dane.Split(',');
Array.Resize(ref tablica, tablica.Length -1);
O co chodzi z tym Append?
**Append **- cytując "Metoda służy do dodawania tekstu na końcu łańcucha(stringa) utrzymywanego przez klasę StringBulider."
Zrobiłem to tak, że czytam każdą linijkę z pliku i dodaje ją do jednego "długiego" stringa, który będzie je wszystkie trzymał, ale trzeba zauważyć, że na końcu każdej linijki brakuje przecinka "zamykającego", więc go również dodaje.
Dalej:
Array.Resize(ref tablica, tablica.Length -1);
Po co to? problem tego rozwiązania z Append jest taki, że na samym końcu tablicy zostaje nam pusty index którego po prostu "wywalamy"
Tutaj jak to wygląda bez tego resize:
Dodatkowo losowanie i użycie tego np. poprzez wyświetlenie przy użyciu MessageBoxa można zrobić np. tak.
(tamten kod)
Random rnd = new Random();
int random_value = rnd.Next(tablica.Length); /// losuje na przedziale <0;tablica.Length)
MessageBox.Show(tablica[random_value]);
string path = "text.csv";
var content = File.ReadLines(path)
.Select(line => line.Split(','))
.SelectMany(word => word)
.ToList();
foreach(string word in content)
Console.WriteLine(word);
Przykład dla struktury pliku przedstawionego przez @WeiXiao. Wszystkie słowa zostaną zapisane do listy (List<string>) ;)
Później już wystarczy wylosować jakąś liczbę z przedziału 0-<długość listy> i pobrać element np. content[randomowaLiczba];
Ja zazwyczaj jak mam coś do zrobienia z plikami CSV to korzystam z tej biblioteki https://joshclose.github.io/CsvHelper/
A ja bym zrobił to zupełnie inaczej... Zamieniłbym w pliku wszystkie znaki końca linii na separator (czyli przecinek), a potem wczytał. Miałbym jedną linię, którą bym wczytał. I ją bym podzielił na wyrazy. Oszczędziłbym bym sobie (i procesorowi) ciągłej operacji na tablicy stringów, które są czasochłonne...
@Marcin.Miga: ale po co zmieniać coś w pliku, skoro można po prostu usprawnić parsowanie?
@WeiXiao: to samo można byłoby z powodzeniem zrealizować bez StringBuildera
, wystarczy string.Join
. No i Convert.ToString
na obiekcie typu StringBuilder
nie ma żadnego sensu, bo zostanie wywołana wersja przyjmująca object
, a ona zrobi po prostu stringBuilder.ToString()
, czyli to, co powinno się tam znaleźć od razu.
Tak czy siak, nie trzeba StringBuildera
, LINQ
ani innych wynalazków, można to zrobić prosto:
var content = File.ReadAllText(@"C:\Temp\textfile.txt");
var result = content.Split(new[] { ',', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
Za parę godzin będę w domu to trochę po sprawdzam l, zapomniałem dodać, że w pliku csv wyrazy nie będą oddzielone przecinkami, wszystkie będą w innej kolumnie, ale to już raczej sam dam radę przerobić jeden z kodów z góry dzięki :)