Odczyt liczb rzeczywistych z pliku

0

Jako, że to mój pierwszy post to witam wszystkich na forum ;)

Chcę odczytać liczby z pliku, a następnie wpisać je do tablicy, jednak nie mogę poradzić sobie z konwersją danych na float. Na forum znalazłem [url=http://4programmers.net/Forum/viewtopic.php?id=154708]ten temat[/url], jednak rozwiązanie tam przedstawione pozwala na wpisanie do tablicy jedynie liczb całkowitych, przy podaniu w danych liczb z miejscami po przecinku program się zawiesza.

Liczby są podane w postaci macierzy, kolejne wiersze rozdzielają przecinki, a kolumny entery.
<code='przyklad'>3.45234,1.32153,0.23233
3.34214,6.43212,0.32452


Czy jest jakiś sposób, żeby "skleić" ciąg znaków z tablicy char w liczbę float? Pomyślałem o zrobieniu tablicy pośredniej, do której będę wpisywać znaki aż do wystąpienia przecinka lub entera, a później całą jej zawartość już jako float wkleję to tablicy wynikowej. Nie mam jednak pomysłu jak to zrobić.

0

siemka
ja robilem tak, ze wczytywalem wszystko do stringa, a potem konwertowalem na floata. Ty bys musial czytac znak po znaku az do znalezienia przecinka. :-).

0

Ale jak to później przekonwertować? Jeśli czytam znak po znaku to dostaję macierz z jednym znakiem w jednej komórce i teraz trzeba to jakoś połączyć i zmienić we float.

0

a strumień wejścia sobie nie poradzi? (nie testowałem)

plik_wejscia >> zmienna_typu_float;
0

Przyklad odczytania zawartosci linijki z pliku i sprawdzenie czy dana wartosc jest typu float:

#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;

int main() {
	ifstream odczyt("plik.txt");
	if(odczyt.good()) {
		string line;
		getline(odczyt, line);
		odczyt.close();

		float value;
		istringstream iss(line);
		iss >> value;
		if(iss.eof() && !iss.fail()) {
			cout << value << endl;
		} else {
			cout << "wczytana wartosc nie jest typu float.\n";
		}
	} else {
		cout << "brak pliku lub plik jest pusty.\n";
	}
	return 0;
}
0

@korushiku no dobra, ale ja w jednej linijce mam tych wartości więcej niż jedną, przed wszelkim sprawdzaniem i innymi działaniami na nich muszę to jakoś podzielić. Jest do tego jakaś konkretna funkcja?
Albo jest jakiś sposób, żeby strumieniowo przesłać do chara tylko x pierwszych znaków, jednocześnie kasując je i 1 dodatkowy (przecinek)?

0

A nie ma w bibliotece <string> jakieś funckji analogicznej do metody Split() z C#? A później tablice stringów potraktować za pomocą atof()?

0
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;

int main() {
	ifstream odczyt("plik.txt");
	if(odczyt.good()) {
		string line;
		while(getline(odczyt, line)) {
			string separator = ",";
			string::size_type lpos = 0, rpos = line.find(separator, 0);
			while(rpos != string::npos) {
				float value;
				istringstream iss(line.substr(lpos, rpos - lpos));
				iss >> value;
				if(iss.eof() && !iss.fail()) {
					cout << value << " ";
				} else {
					cout << "wczytana wartosc nie jest typu float.\n";
				}
				lpos = rpos + 1;
				rpos = line.find(separator, lpos);
			}
			cout << "\n";
		}
		odczyt.close();
	} else {
		cout << "brak pliku lub plik jest pusty.\n";
	}
	return 0;
}

przy czym linie musialyby sie rowniez konczyc przecinkiem

3.14,2.4421,2.55,
1.23,9.78,12.3,
0.94,1.0,2.9823,

Pozna pora i nie chce mi sie juz myslec, ale mysle, ze google daloby odpowiedz na haslo "c++ split" ;).

0
char linia[1024];
double liczba;
FILE *plik = fopen("plik.txt", "w");
int len;
   while(fgets(linia, 1024, plik)
      {
      len=strlen(linia);
      for(int i=len-1; i>=0; i--)
         if(linia[i]==',')
            {
            liczba=atof(&linia[i+1]);  //liczby z linii pobierane od tyłu
            linia[i]='\0';
            }

      }
0

Pokombinowałem nieco z pobieraniem znak po znaku i osiągnąłem coś takiego: (Co prawda jest to cholernie zasobożerne, ale na razie chcę tylko, żeby to działało :P )

void tablica (int kolumny, int wiersze)						// funkcja zamienia znaki z pliku na tablice typu double
{
char ciag [128], znak=0;
double wynik[256][256], liczba=0, max, min;
FILE *plik = fopen("dane.txt", "r");
int k=0, i=0, j=0, kol=0, wier=0;
do{									//petla powtarzajaca nastepne, az do konca pliku	
	do{								//petla przeskakujaca do nastepnego wiersza
	while((znak=fgetc(plik))!=','&&znak!='\n'&&znak!=EOF)		//petla wczytujaca zawartosc kolumny do tablicy
  {           
	ciag [k]=znak;
	k++;
  }
	ciag[k+1]='\0';
liczba = atof(ciag);				//zamiana char na double
wynik[i][j]=liczba;
k=0;
++i;
}while(znak!='\n'&&znak!=EOF);
i=0;
++j;
}while(znak!=EOF);
fclose(plik);
/*tablica jest wczytana, czas na wypisywanie*/

Problem jest taki, że przy pliku danych, jaki dostałem, otrzymuję złe wartości. Dopisałem do programu małą pętlę, sprawdzającą czy wszystkie znaki w pliku są "legalne" i wywala mi ona program. Mógłby ktoś sprawdzić czy ta pętla ma odpowiednie warunki logiczne dla powyższego kodu? Byłbym bardzo wdzięczny. Na moim pliku testowym (3x3), nic takiego się nie dzieje, ale wolałbym, żeby ktoś doświadczony przyjrzał się kodowi ;)

	if (znak!='-'&&znak!='0'&&znak!='1'&&znak!='2'&&znak!='3'&&znak!='4'&&znak!='5'&&znak!='6'&&znak!='7'&&znak!='8'&&znak!='9'&&znak!='.'&&znak!=','&&znak!=EOF&&znak!='\n')
	{
		printf ("Nieprawidlowy znak w pliku, popraw!");
	return(1);
	}

EDIT:
Hmm, po wrzuceniu pliku do calc'a i policzeniu sumy wszystkich komórek otrzymuję wartość (raczej poprawną). Teraz pytanie czy to kwestia błędów w moim kodzie, czy w pliku jest jakiś błąd bez wpływu na OpenOffice'a...

0

Może tak?

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;

int main(int argc, char **argv){

    ifstream we("we.txt");
    string pomoc;
    string spacja = " ";
    
    
    while(!we.eof())
    {
     getline(we,pomoc);
     istringstream i(pomoc);
     while(i >> spacja)
           cout << spacja << "\n";              
    }
    
    return 0;
}
0

Podaję przykład. Nie jest to odczyt z pliku, ale wyciąganie double ze zdefiniowanego stringa. Czytaj z pliku linia po linii jako string i otrzymasz to samo.

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

 int main()
  { 
   string stp="",st="12.23,23.0,2.222,3.4";  
   double n; 
   int dl=st.length();
    for(int i=0;i<dl;i++)
     {
      stp=stp+st[i];
       if((st[i]==',')||(i==dl-1))
        {
         n=atof(stp.c_str());
         stp="";
         cout<<n<<endl;                         
        }
     }                                  
   getch();
   return 0;
   }

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