čtení double z textového souboru – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

čtení double z textového souboru – C / C++ – Fórum – Programujte.comčtení double z textového souboru – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené — příspěvek s řešením.
mateo0
Duch
28. 7. 2011   #1
-
0
-

Ahoj, mám textový soubor, který na každé řádce obsahuje šest čísel (double) oddělených mezerou. Chtěl bych vždycky 4 řádky načíst (pole x1..x3, y1..y3) a lagrangeovsky je interpolovat (fce lagrange() - funkční), vypsat nalezené hodnoty v nule a pak vzít další 4 řádky atd. až do konce souboru. Následující kód mi funguje, pokud jsou řádky v souboru pouze 4, tedy provede se jedno zpracování. Už při osmi program kolabuje. Marně hledám chybu. Pomohl by někdo?

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string.h>
#include <stdio.h>

using namespace std;

double lagrange(double xcoords[],double ycoords[], double xin, int n) {
       
double fx = 0;  //the value of f(x)
for(int i=0; i<n; i++){
   double Lg = 1;
   for(int j=0; j<n; j++){
      if(i != j){
         Lg *= (xin-xcoords[j])/(xcoords[i]-xcoords[j]);
      }
   }
   fx += Lg*ycoords[i];
}

   return (fx);
}

int main(int argc, char *argv[])
{
  int rad = 4;                     // počet řádek a zároveň počet proložených bodů  
                                   //
  double x1[rad], y1[rad];
  double x2[rad], y2[rad];
  double x3[rad], y3[rad];   
   
  int i = 0,delka;
  string line;  
  ifstream myfile;
  myfile.open ("test.txt");
  if (myfile.is_open()) {   
     getline(myfile,line);
     while (! myfile.eof() )  {          
      
              delka = line.size();
              char* s = new char [delka];
              strcpy(s, line.c_str());
              char * pEnd;
              y1[i] = strtod (s,&pEnd);
              x1[i] = strtod (pEnd,&pEnd);
              y2[i] = strtod (pEnd,&pEnd);
              x2[i] = strtod (pEnd,&pEnd);
              y3[i] = strtod (pEnd,&pEnd);
              x3[i] = strtod (pEnd,NULL);
              delete [] s;
              getline(myfile,line);                      
              i++;
                
        if (i == rad) {                     
           cout << lagrange(x1,y1,0,rad) << " "
                << lagrange(x2,y2,0,rad) << " "
                << lagrange(x3,y3,0,rad) << endl;
           i = 0;  
         }             
                                                                            
      }

  myfile.close();     
                     
  }
 else cout << "Soubor neotevren!";

    system("PAUSE");
    return EXIT_SUCCESS;
}

Soubor "test.txt" vypadá takto

6.27664 -2.18947e-007 6.27664 -2.18947e-007 6.27663 -2.19064e-007
6.28091 -7.5975e-008 6.28091 -7.5975e-008 6.28091 -7.60931e-008
6.28519 6.69988e-008 6.28519 6.69988e-008 6.28519 6.688e-008
6.28947 2.09971e-007 6.28947 2.09971e-007 6.28946 2.09851e-007

případně osmiřádková verze

6.27664 -2.18947e-007 6.27664 -2.18947e-007 6.27663 -2.19064e-007
6.28091 -7.5975e-008 6.28091 -7.5975e-008 6.28091 -7.60931e-008
6.28519 6.69988e-008 6.28519 6.69988e-008 6.28519 6.688e-008
6.28947 2.09971e-007 6.28947 2.09971e-007 6.28946 2.09851e-007
12.5618 -1.51992e-007 12.5618 -1.51992e-007 12.5618 -1.52465e-007
12.5661 -9.01916e-009 12.5661 -9.01916e-009 12.5661 -9.4929e-009
12.5704 1.33954e-007 12.5704 1.33954e-007 12.5704 1.33479e-007
12.5747 2.76924e-007 12.5747 2.76924e-007 12.5746 2.76448e-007
Nahlásit jako SPAM
IP: 88.101.70.–
Řešení
liborb
~ Redaktor
+18
Guru
29. 7. 2011   #2
-
0
-
Vyřešeno Nejlepší odpověď

Dle VS 3 chyby:

- místo #include <string.h> má být jen #include <string>

- proměnná rad musí být konstantní: const int rad = 4;
(to ti přece nemohlo jít přeložit   )

- a ta skutečně záludná (a přitom tak běžná) chyba je, že si alokuješ paměť pro řetězec délky delka a pak do něj nakopíruješ data o délce delka + 1, protože je řetězec ukončený nulovým znakem, takže šáhneš do paměti kam nesmíš .... +1 to řeší:

delka = line.size() + 1; 

A jinak tvůj kód očekává na konci textového souboru prázdný řádek.

Nahlásit jako SPAM
IP: 78.80.52.–
mateo0
Duch
29. 7. 2011   #3
-
0
-

#2 liborb
Přeložit to šlo. Vycházel jsem mimo jiné z následujícího příkladu z http://www.cplusplus.com/…ial/dynamic/ , kde je příklad

// rememb-o-matic
#include <iostream>
#include <new>
using namespace std;

int main ()
{
  int i,n;
  int * p;
  cout << "How many numbers would you like to type? ";
  cin >> i;
  p= new (nothrow) int[i];
  if (p == 0)
    cout << "Error: memory could not be allocated";
  else
  {
    for (n=0; n<i; n++)
    {
      cout << "Enter number: ";
      cin >> p[n];
    }
    cout << "You have entered: ";
    for (n=0; n<i; n++)
      cout << p[n] << ", ";
    delete[] p;
  }
  return 0;
}

tam snad taky není const int i, nebo je to nějak schovaný?

A ještě jedna otázka. Dal jsem příkaz getline() na začátek cyklu while místo před něj a na konec a funguje to bez posledního prázdného řádku. Znamená to tedy, že když si getline přečte poslední řádek (za kterým je, předpokládám, eof), tak řádek zpracuje normálně a přitom ale myfile.oef() už bude true? To je něco, čím jsem si nebyl jistý a jednoznačnou odpověď jsem na to taky nenašel.

Nahlásit jako SPAM
IP: 88.101.70.–
KIIV
~ Moderátor
+43
God of flame
29. 7. 2011   #4
-
0
-

#2 liborb
string.h bylo taky dobre... ma tam byt jak <string> tak <string.h> (jinak zname jako <cstring> v c++)

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
liborb
~ Redaktor
+18
Guru
29. 7. 2011   #5
-
0
-

#3 mateo
Tam je NEconst int i správně, protože mají dynamickou alokaci paměti. Ty máš staticky definované ple, takže velikost musí být známá v době překladu, a proto musí být const nebo ještě lépe používat definovanou konstantu, něco jako:

#define DELKA_POLE	4

A dále, když přečteš řádek, tak v něm máš nějaká data. Pokud pak testuješ konec souboru a ten řádek byl poslední, tak samozřejmě konec souboru je, tobě program skončí a zůstanou ti nezpracovaná data.

#4 KIIV
Mě VS jenom se string.h hlásilo, že nezná getline a změna na string pomohla, možná i proto, že se to tak píše v dokumentaci :)

Nahlásit jako SPAM
IP: 78.80.52.–
liborb
~ Redaktor
+18
Guru
29. 7. 2011   #6
-
0
-

A ještě doplnění o ukázku principu, jak by se to dalo řešit:

while(!myfile.eof()) {
	// neni konec souboru, tak nacti radku
	getline(myfile, line);

	// zpracovani nactene radky

	// podminka na nactene 4 radky
	if (i == DELKA_POLE) {
	}                
}
Nahlásit jako SPAM
IP: 78.80.52.–
KIIV
~ Moderátor
+43
God of flame
29. 7. 2011   #7
-
0
-

#5 liborb
a strcpy ti nic nehlasilo? napriklad implicitni deklarace? (to je totiz zase z cstring) aspon G++ takovy veci hlasi

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
mateo0
Duch
29. 7. 2011   #8
-
0
-

#7 KIIV
Nehlásilo. Mám Bloodshed Dev C++, mimochodem.

Nahlásit jako SPAM
IP: 88.101.70.–
liborb
~ Redaktor
+18
Guru
29. 7. 2011   #9
-
0
-

#7 KIIV
Nic resp. jenom to, že strcpy je unsafe a má se použít strcpy_s .. bla bla ... Ale je to zajímavé, hledal jsem, jestli ten include není někde schovaný a nenašel jsem. No ... furt lepší, když to funguje a nemám to tam, než abych to tam měl a nefungovalo to   

Nahlásit jako SPAM
IP: 78.80.52.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 65 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý