`Čakars` daudzu stundu garumā

Viss sākās ar to, ka gribēju iekš C++ uztaisīt programmiņu.. Nu, ne jau ko sarežģītu, tādu pavisam vienkāršu, kas no dota bināra faila (kas satur pozitīvus un negatīvus veselus skaitļus kā ierakstus) izveido citu bināru failu (arī ar šiem pašiem veselajiem skaitļiem kā ierakstiem), vienkārši saliekot tos citādā secībā – vispirms negatīvos, tad pozitīvos. Papildus nosacījums – ieejas failu nedrīkst uzreiz visu ielasīt atmiņā, tas ir, jāstrādā pa tiešo ar failu, nevis ar operatīvo atmiņu.

Pēc aptuveni divu dienu ilgas čakarēšanās, kuras laikā paspēju nolamāt sevi dažādos sliktos vārdos, nespēdams saprast, kādēļ mana triviālā programma nekādi negrib strādāt. Pagāja laiks un es lokalizēju kļūdu līdz šādai funkcijai, kura pēc būtības ir (atkal jau) līdz nelabumam triviāla – dotajā failā visi skaitļi tiek pabīdīti par vienu pozīciju pa labi (pirmā pozīcija tādejādi paliek `tukša`):

void moveRecords(fstream & f) {
f.seekg(0,ios::beg);
int x=0,y=0;
f.read((char *)&x,sizeof(int));
if (f) {
  f.read((char *)&y,sizeof(int));
  while (f) {
   f.seekp(-4,ios::cur);
   f.write((char *)&x,sizeof(int));
   x=y;
   f.read((char *)&y,sizeof(int));
  }
}
f.clear();
f.seekp(0,ios::end);
f.write((char *)&x,sizeof(int));
f.clear();
}

It kā viss vienkārši – tik lasām un rakstām! Bet nē, nolasīti tiek tikai daži skaitļi un tad pēkšņi kārtējā lasīšanas operācija izrādās neveiksmīga, līdz ar ko iestājas lasīšanas kļūda, līdz ar ko cikla nosacījums kļūst aplams, līdz ar ko cikls beidzas pāragri.

Gāja laiks un beigu beigās konstatēju, ka pierakstot vienu papildus rindu aiz (der arī pirms) rindas `x=y;` viss uzreiz strādā korekti. Šī mistiskā rinda izskatās šādi:

f.tellp();

Njā😀 Ir jāizsauc funkcija, kas pasaka, kurā vietā failā šobrīd atrodos!? Kāda velna pēc?? Pat rezultātu nekur nevajag likt.. Nu neko, meklēju tīmeklī, ko īsti šī funkcija dara, domādams, ka varbūt tai ir kādi slēpti blakusefekti.. Bet nē, visur izskaidrota tikai standarta uzvedība, nekas vairāk.

Stāsts beidzās ar to, ka konstatēju, ka šāda dīvaina uzvedība ir tikai Dev-C++ kompilatoram, savukārt, piemēram, Borland C++ Builder 5. versija strādā kā nākas arī bez šādas bezjēdzīgas rindas uzrakstīšanas. Tādējādi man tagad nav skaidrs, ko darīt – kā novērst šo problēmu Dev-C++, jo man šajā situācijā diemžēl jāizmanto tieši šis kompilators.. Kādam ir idejas? Komentāri jūsu rīcībā!

4 thoughts on “`Čakars` daudzu stundu garumā

  1. Dev-C++ nav kompilators – tā ir IDE, kas izmanto GCC kompilatoru.

    Bet problēma ir tur, ka vienlaicīgi izmantot put un get pointerus (seekg/seekp) nebūs labi. c++ iostreami var sākt gļukot – tie nav paredzēti tā lietot. Ar BCB++ tev vienk paveicās, ka strādā.

    Labāk ir pirms katras rakstīšanas/lasīšans novietot to korektā pozīcijā. Es to darītu apmēram šādi (kods nav pārbaudīts): http://paste.php.lv/2c09e7d92c62f539aae1d6362d6425ca?lang=c

  2. Nezinu par izmantotajiem kompilatoriem, bet nu funkcija ir uzrakstiita garaam, jeb pareizaak sakot – peec std c++ behaviours ir “undefined”, liidz ar to ko tur briiniities par atshkjiriibaam starp kompilatoriem. STL streamiem write/read poziicijas ir divas dazhaadas lietas. Tas noziimee, ka:
    f.seekp(-4,ios::cur);
    f.write((char *)&x,sizeof(int));
    ciklaa visu laiku rakstiis vienaa un tajaa pashaa vietaa neatkariigi no taa kaadi seekg un read veel tiek izmantoti. Shajaa situaacijaa vispaar sanaak pirms faila saakuma, liidz ar to rezultaats “undefined”.

  3. bubu, paldies par ideju – tiešām laikam var pieturēties pie stila pirms katras operācijas uzstādīt faila norādi.

    a, nu tā vis laikam nav – seekg un seekp failam, kas atvērts gan lasīšanas, gan rakstīšanas režīmā, darbojas identiski. Sākumā likās, ka varbūt tās ir divas dažādas norādes, bet, pārbaudot ar tellg un tellp funkcijām, secināju, ka gan lasīšanas, gan rakstīšanas operācija pabīda uz priekšu `abas` šīs norādes, kas vedina uz domām, ka norāde patiesībā ir tikai viena (pat, ja ir divas, tās mainās sinhroni un nekādu jaunu informāciju tādejādi nedod).

  4. Tu nedrīksti pieņemt, ka tā ir viena un tā pati, jeb divas. Kā jau a saka – tāda rīcība novedīs pie “undefined” rezultāta. C++ standartā nav apgalvots, ka tām norādēm jābūt 2, vai 1 un kā jāsadarbojas kopā. Tāpēc, katrs C++ standartbibliotēkas veidotājs to implementē pa savam prātam – respektīvi uz to nedrīkst neko paļauties. Ar vienu vendora bibliotēku strādās, ar otru dažreiz strādās, citreiz nē, bet ar trešo vispār iespējams kods krašos.

Komentēt

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Mainīt )

Twitter picture

You are commenting using your Twitter account. Log Out / Mainīt )

Facebook photo

You are commenting using your Facebook account. Log Out / Mainīt )

Google+ photo

You are commenting using your Google+ account. Log Out / Mainīt )

Connecting to %s