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 |
nu scrie corect in fisier
Last Updated: Feb 22 2013 03:26, Started by
gyabluesky
, Feb 13 2013 22:06
·
0
#1
Posted 13 February 2013 - 22:06
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
Posted 13 February 2013 - 22:19
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
Posted 13 February 2013 - 22:23
Quote Problema este ca in fisierul de ouput imi repeta de foarte multe ori ultimul analizezi de ce este apelata de mai multe ori |
#4
Posted 13 February 2013 - 22:23
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
Posted 13 February 2013 - 22:38
autoplayer, 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 MarianG, 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
Posted 13 February 2013 - 22:42
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
Posted 13 February 2013 - 22:48
yonut_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
Posted 13 February 2013 - 23:13
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
Posted 13 February 2013 - 23:49
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. 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. |
#10
Posted 14 February 2013 - 00:02
|
#11
Posted 15 February 2013 - 02:37
alexcrist, 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
Posted 15 February 2013 - 08:31
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
Posted 15 February 2013 - 18:31
alexcrist, 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); } } |
Anunturi
▶ 1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users