Jump to content

SUBIECTE NOI
« 1 / 5 »
RSS
Manere clasice mobila sau push to...

Contact pe piele cu sangele altei...

metoda constantelor de scurtcircuit

video file info
 Nu pot raspunde: Huawei P10

Cod cursor website

Cum se iese la pensie la munca di...

Inlocuire Tranzistor 4410 BA622T ...
 CASS pe veniturile din DOBANZI

Masina de spalat rufe Bosch

Spatiu prea mare inainte de titlu

Recomandare banca pentru firma
 Photoscape, unde?

Prima World HD

Recomandare bicicleta MTB copil 1...

Cum pot reda niște inregistr...
 

nu scrie corect in fisier

- - - - -
  • Please log in to reply
13 replies to this topic

#1
gyabluesky

gyabluesky

    New Member

  • Grup: Members
  • Posts: 5
  • Înscris: 13.02.2013
Incerc sa citesc din fisier si sa scriu intr-un alt fisier. Problema este ca in fisierul de ouput imi repeta de foarte multe ori ultimul
rand citit din input.

Acesta este codul:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

FILE* openFile(char fileName[], char mode[]) {

FILE *file;
file = fopen(fileName, mode);

if(file == NULL) {
	 printf("Imposibil de deschis");
	 exit(1);
}

return file;
}

int main() {

FILE *file, *output;
char query[80], doc[80];
int nr_doc, nr_query, i;

file = openFile("input.in", "rt");
output = openFile("output.in", "wt");

while(!feof(file)) {

	 fscanf(file, "%d", &nr_doc);
	 fprintf(output, "%d", nr_doc);

	 for(i = 0; i < nr_doc; i++) {
		 fgets(doc, 40, file);
		 fprintf(output, "%s", doc);
	 }

	 fscanf(file, "%d", &nr_query);
	 fprintf(output, "%d", nr_query);

	 for(i = 0; i < nr_query; i++) {
		 fgets(query, 40, file);
		 fprintf(output, "%s", query);
	 }
}
fclose(file);
fclose(output);
return 0;
}



Fisierul input este urmatorul:
3
date.in
date2.in
date3.in
5
note & pen
sea | starfish
kika
book
notebook & key

Iar fisierul output este:
3
date.in
date2.in
date3.in
5
note & pen
sea | starfish
kika
book
notebook & keynotebook & keynotebook & keynotebook & keynotebook & keynotebook & keynotebook & keynotebook & keynotebook & key...

Unde este greseala?

De mentionat ca programul nu se inchiei cu succes, nu returneaza 0.

Edited by gyabluesky, 13 February 2013 - 22:24.


#2
autoplayer

autoplayer

    Active Member

  • Grup: Members
  • Posts: 1,486
  • Înscris: 08.01.2010
feof am observat ca nu functioneaza bine. Incearca ceva de genu':

char s[100];

while (fscanf(file,"%s",&s)!=EOF){
}


Sau, incearca sa verifici si inainte de for (dupa ce l-ai citit pe nr_doc sa pui un if cu feof care sa contina intre {} restul codului).

while(!feof(file)) {
		 fscanf(file, "%d", &nr_doc);
		 fprintf(output, "%d", nr_doc);
		 if (!feof(file)){


		 for(i = 0; i < nr_doc; i++) {
				 fgets(doc, 40, file);
				 fprintf(output, "%s", doc);
		 }
		 fscanf(file, "%d", &nr_query);
		 fprintf(output, "%d", nr_query);
		 for(i = 0; i < nr_query; i++) {
				 fgets(query, 40, file);
				 fprintf(output, "%s", query);
		 }


		 }
}
fclose(file);
fclose(output);
return 0;
}


Edited by autoplayer, 13 February 2013 - 22:26.


#3
MarianG

MarianG

    be that as it may

  • Grup: Moderators
  • Posts: 31,500
  • Înscris: 10.08.2005

Quote

Problema este ca in fisierul de ouput imi repeta de foarte multe ori ultimul
pai vezi frumos, unde ai instructiunea respectiva
analizezi de ce este apelata de mai multe ori

#4
yonut_a

yonut_a

    Trala la la la

  • Grup: Senior Members
  • Posts: 3,948
  • Înscris: 03.08.2008
greseala ta e aici

for(i = 0; i < nr_doc; i++)
ai nr_doc dar fiindca ai pus conditia < citesti doar nr_doc-1, pe urma totul se da peste cap pe acolo

for(i = 0; i <= nr_doc; i++)


le fel si la celalalt for

#5
gyabluesky

gyabluesky

    New Member

  • Grup: Members
  • Posts: 5
  • Înscris: 13.02.2013

View Postautoplayer, on 13 februarie 2013 - 22:19, said:

feof am observat ca nu functioneaza bine. Incearca ceva de genu':



Ai testat partea de cod pe care ai recomandat-o? Pentru ca mie imi apar traznai in plus in fisierul de output :)

View PostMarianG, on 13 februarie 2013 - 22:23, said:

pai vezi frumos, unde ai instructiunea respectiva
analizezi de ce este apelata de mai multe ori

Ar trebui sa imi scrie in fisier exact ce citeste, al doilea for nu ar trebui sa permita aparitia a mai mult de 5 linii in fisierul de output

#6
yonut_a

yonut_a

    Trala la la la

  • Grup: Senior Members
  • Posts: 3,948
  • Înscris: 03.08.2008
Ar trebui sa imi scrie in fisier exact ce citeste, al doilea for nu ar trebui sa permita aparitia a mai mult de 5 linii in fisierul de output

vad ca ai bagat in seama sfaturile tuturor dar mai putin al meu.

iti repet. for urile tale nu citest nici 3 nici 5 linii din fisier ci 2 respectiv 4.

asta impreuna cu while ul ala ca oricum nu isi avea rostul da totul peste cap

#7
gyabluesky

gyabluesky

    New Member

  • Grup: Members
  • Posts: 5
  • Înscris: 13.02.2013

View Postyonut_a, on 13 februarie 2013 - 22:42, said:

Ar trebui sa imi scrie in fisier exact ce citeste, al doilea for nu ar trebui sa permita aparitia a mai mult de 5 linii in fisierul de output

vad ca ai bagat in seama sfaturile tuturor dar mai putin al meu.

iti repet. for urile tale nu citest nici 3 nici 5 linii din fisier ci 2 respectiv 4.

asta impreuna cu while ul ala ca oricum nu isi avea rostul da totul peste cap

hm.. interesant. multumesc frumos :)

mi-ar fi de folos si o explicatie. de ce '<=' ?

#8
yonut_a

yonut_a

    Trala la la la

  • Grup: Senior Members
  • Posts: 3,948
  • Înscris: 03.08.2008
Primul fgets iti citeste un caracter din buffer.Daca faci o cit
ire  inaintea for ului vei putea lasa conditia initiala strict mai mic

Edited by yonut_a, 13 February 2013 - 23:14.


#9
alexcrist

alexcrist

    Watchdog

  • Grup: Moderators
  • Posts: 9,322
  • Înscris: 02.02.2006
yonut_a, câte valori sunt în intervalul [0,5]? A se nota, interval închis. Dacă nu cunoști noțiunea de interval, spune câte valori sunt în mulțimea {0, 1, 2, 3, 4, 5}. Dar, altfel spus, dacă pornești un contor de la 0, și te oprești la 5 inclusiv, câte valori ai numărat?

Dacă la vreuna dintre întrebările astea, răspunsul tău e 5, atunci ia-o de la capăt. Și repetă calculele până îți dă 6. Posted Image

for-urile erau corecte. Dacă pornești o parcurgere de la 0, atunci te oprești la maxim -1.

Buba în cod este că tu citești exact tot ce trebuie în prima iterație. Conform documentației, feof returnează o valoare nenulă atunci când indicatorul end-of-file a fost setat. Iar acel indicator NU se setează atunci când atingi sfârșitul de fișier, ci atunci când încerci să-l depășești. În caz concret:
dacă ai 5 valori într-un fișier, și citești 5 din ele, feof va returna 0 (indicatorul end-of-file nu e setat). Abia când încerci a șasea citire, citirea va da eroare, iar acel indicator va fi setat. Abia atunci feof va returna valoare nenulă.

Deci da, feof funcționează bine. Doar că nu l-ai folosit bine. Posted Image

#10
MarianG

MarianG

    be that as it may

  • Grup: Moderators
  • Posts: 31,500
  • Înscris: 10.08.2005

View Postgyabluesky, on 13 februarie 2013 - 22:38, said:

Ar trebui sa imi scrie in fisier exact ce citeste, al doilea for nu ar trebui sa permita aparitia a mai mult de 5 linii in fisierul de output
ar trebui sa scrie in fisier exact ce ii spui

nu calculatorul greseste ci programatorul

#11
gyabluesky

gyabluesky

    New Member

  • Grup: Members
  • Posts: 5
  • Înscris: 13.02.2013

View Postalexcrist, on 13 februarie 2013 - 23:49, said:


for-urile erau corecte. Dacă pornești o parcurgere de la 0, atunci te oprești la maxim -1.


Spui ca for-urile erau corecte, nu te contrazic si mie mi se pare logic sa inceapa la 0 si sa se opreasca la maxim - 1, doar ca daca incerc sa mai citesc o valoare  oarecare la finalul functiei
while pentru a seta indicatorul end-of-file, tot repeta ultimul rand.

Ideea de a incepe la 0 si a te opri la maxim functioneaza, doar ca apare unu mic inconvenient, la al doilea for citeste un sir in plus de dimensiune 1. Nu ar fi chiar asa o mare
problema, dar eu folosesc aceasta citire intr-un program mai marisor.

Ai putea sa imi dai ceva mai multe indicatii?

Nota: ma intereseaza mai mult citirea din fisier, decat scrierea.

#12
alexcrist

alexcrist

    Watchdog

  • Grup: Moderators
  • Posts: 9,322
  • Înscris: 02.02.2006
Dacă mergi pe ghicite, o să dai de probleme de n-ai să știi de unde apar. Nu așa se învață programarea.

E normal să-ți repete ultimul șir citit, dacă tu citești tot un șir (nu întreg sau altceva) și dacă folosești aceeași variabilă query. Dacă rețin bine, documentația spune că fscanf (și scanf și alte variații) nu modifică valoarea existentă într-o variabilă, dacă nu are ce stoca în ea. Adică: tu ai o variabilă X cu valoarea 5 și încerci să citești în X, iar citirea dă eroare, X rămâne 5 iar EOF e setat.
Rulare pas cu pas știi să faci? Fă-ți un debug pe propriul program și vezi unde îți repetă valorile.

O abordare pe care o prefer eu este de genul:
citire contor inițial (nrdoc la tine)
while (!feof)
{
afișezi contorul, dacă ai nevoie
blablabla alte operații

citire contor inițial (nrdoc la tine)
}


Astfel, dacă nu se poate citi contorul, nu mai repetă bucla. Mai mult, dacă nici măcar primul contor nu se poate citi, nu intră deloc în buclă, ceea ce poate fi extrem de util în anumite cazuri.

#13
gyabluesky

gyabluesky

    New Member

  • Grup: Members
  • Posts: 5
  • Înscris: 13.02.2013

View Postalexcrist, on 15 februarie 2013 - 08:31, said:

documentația spune că fscanf (și scanf și alte variații) nu modifică valoarea existentă într-o variabilă, dacă nu are ce stoca în ea. Adică: tu ai o variabilă X cu valoarea 5 și încerci să citești în X, iar citirea dă eroare, X rămâne 5 iar EOF e setat.


cred ca faci o mare confuzie. adica urmatoarea secventa de cod nu functioneaza?

int main() {
	FILE *f;
	char query[40];
	f = fopen("input.in", "rt");
	while(!feof(f)) {
		fscanf(f, "%s", query);
		printf("%s\n", query);
	}
	return 0;
}


Functioneaza chiar foarte bine.

In cazul in care nu s-a observat pana acum, eu am folosit in programul de mai sus atat fscanf cat si fgets. Prima functie citeste pana intalneste spatiu si acolo ramane. Folosind apoi cea de-a doua functie, fgets (care citeste pana intalneste sfarsit de linie sau pana la dimensiune - 1 ) va citi de pe acelasi rand de pe care a citit si fscanf, ceea ce nu se doreste. Acesta este si motivul pentru care aparea un sir in plus, de dimensiune 1.

O solutie, as spune eu, eleganta ar fi sa se citeasca inaintea fiecarui for cate un sir ca in exemplul urmator:

while(!feof(file)) {

		fscanf(file, "%d", &nr_doc);

		fgets(doc, 40, file);
		for(i = 0; i < nr_doc; i++) {
			fgets(doc, 40, file);
			puts(doc);
		}

		fscanf(file, "%d", &nr_query);

		fgets(query, 40, file);
		for(i = 0; i < nr_query; i++) {
			fgets(query, 40, file);
			puts(query);
		}
	}



#14
nucL3ar

nucL3ar

    Junior Member

  • Grup: Members
  • Posts: 45
  • Înscris: 23.08.2009
A&C detected.

Anunturi

Chirurgia cranio-cerebrală minim invazivă Chirurgia cranio-cerebrală minim invazivă

Tehnicile minim invazive impun utilizarea unei tehnologii ultramoderne.

Endoscoapele operatorii de diverse tipuri, microscopul operator dedicat, neuronavigația, neuroelectrofiziologia, tehnicile avansate de anestezie, chirurgia cu pacientul treaz reprezintă armamentarium fără de care neurochirurgia prin "gaura cheii" nu ar fi posibilă. Folosind tehnicile de mai sus, tratăm un spectru larg de patologii cranio-cerebrale.

www.neurohope.ro

1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users

Forumul Softpedia foloseste "cookies" pentru a imbunatati experienta utilizatorilor Accept
Pentru detalii si optiuni legate de cookies si datele personale, consultati Politica de utilizare cookies si Politica de confidentialitate