Dakle, ovo bi bilo %8.3f
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
float broj = 55.345643;
cout.width(8); cout<< setprecision(5) << broj;
}
Dakle, ovo bi bilo %8.3f
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
float broj = 55.345643;
cout.width(8); cout<< setprecision(5) << broj;
}
Kad si već spomenuo, kako sa cout napraviti neki formatirani ispis, tipa %5d, %2.5f i sl?
Kako bez sscanf iz stringa iščitat brojeve? npr s="evo broja: 55", pa radimo sscanf(s,"%s: %d",s1,&broj)
Jesi probao scanf("%[0123456789],nešto") ? Tako ti čita samo ono u zagradi, tj. u tvom slučaju brojeve.
EDIT: BTW, zna li netko kako da napravim upis u datoteku? Profesor nam to nije baš nešto objasnio u skriptama (nešto tipa-lakše je čiti nego pisat) a u 2 knjige koje imam nisam našao nešto opširnije.
Ovdje ti nije bez veze data struktura, u stvari traži se od tebe da zapisuješ podatke u binarnu datoteku u blokovima
Pogledaj ovaj topic i moj post koji je zadnj po redu:
http://www.bug.hr/forum/topic/programiranje/cc-koristenje-fscanf/80489.aspx
Pogledaj ovaj topic i moj post koji je zadnj po redu:
http://www.bug.hr/forum/topic/programiranje/cc-koristenje-fscanf/80489.aspx
Binarnu? Koliko sam shvatio, inače se upisuje u tekstualnu, a u binarnu tek kada se doda b. Npr. Upis u datoteku "datoteka.txt".
Pogledaj ovaj topic i moj post koji je zadnj po redu:
http://www.bug.hr/forum/topic/programiranje/cc-koristenje-fscanf/80489.aspx
Binarnu? Koliko sam shvatio, inače se upisuje u tekstualnu, a u binarnu tek kada se doda b. Npr. Upis u datoteku "datoteka.txt".
Točno, koristiš fwrite, a ne fprintf, i kod otvaranja datoteke staviš b, baš kako sam napisao u programu, imaš i link na stranicu gdje opisuju rad sa upisom u binarnu datoteku
Poanta je u tome da odjednom upišeš cijelu strukturu u binarnu datoteku u blokovima
Može li mi netko reći gdje driješim u ovim naredbama:
FILE *fopen(const char *datoteka, const char *a++);
if (fopen(datoteka, a++)==NULL) printf ("\n Pogreska u otvaranju datoteke! \n\n");
fclose;
referenca ovdje
Problem u tvom kodu je sto file handle izgubis, te drugi parametar fopen funkcije ti takoder treba biti const char, znaci moras staviti u navodnike drugi parametar.
ovako se to radi:
FILE *fh;
fh = fopen("nesto.dat", "rb");
if (fh!=NULL)
{
//neki kod ovdje
fclose(fh);
}
referenca ovdje
ovako se to radi:
FILE *fh;
fh = fopen("nesto.dat", "rb");
if (fh!=NULL)
{
//neki kod ovdje
fclose(fh);
}
A što je taj "rb"? Ne bi li trebao stavljati na to mjesto mod? Znaš li kako da pohranim strukturu u datoteku?
A što je taj "rb"? Ne bi li trebao stavljati na to mjesto mod? Znaš li kako da pohranim strukturu u datoteku?
To i jest mod, "r" read (open file for reading) i "b" binary (open file in binary mode), ti ces vjerojatno koristiti nekakav drugi mod, ovo sam samo bubnuo iz glave. Htio sam ti pokazati kako to mora ici pod navodnike, to si radio krivo. Kao i sto gubis file handle, da bi spremao u datoteku treba ti file handle ne smijes ga samo tako odbaciti.
Za spremanje struktura u datoteku pogledaj si onaj link koji ti je floki savjetovao.
Evo ti popis svih modova:
"r" Open a text file for reading
"w" Create a text file for writing
"a" Append to a text file
"rb" Open a binary file for reading
"wb" Create a binary file for writing
"ab" Append to a binary file
"r+" Open a text file for read/write
"w+" Create a text file for read/write
"a+" Open a text file for read/write
"rb+" Open a binary file for read/write
"wb+" Create a binary file for read/write
"ab+" Open a binary file for read/write
#include <stdlib.h>
#include <stdio.h>
typedef struct
{
int a;
int b;
char s;
char tekst[25];
float c;
} struktura;
int main()
{
struktura test, test2;
FILE *fh;
//dodaj vrijednosti elementima strukture
test.a=50;
test.b=480;
test.s='x';
sprintf(test.tekst, "hello world");
test.c=3.14;
//otvori datoteku, spremi strukturu, zatvori datoteku
fh=fopen("test.dat", "wb");
fwrite(&test, sizeof(test), 1, fh);
fclose(fh);
//otvori datoteku, procitaj strukturu, zatvori datoteku
fh=fopen("test.dat", "rb");
fread(&test2, sizeof(test), 1, fh);
fclose(fh);
//ispisi vrijednosti elemenata procitane strukture
printf("%d\n", test2.a);
printf("%d\n", test2.b);
printf("%c\n", test2.s);
printf("%s\n", test2.tekst);
printf("%1.2f\n", test2.c);
system("pause");
return 0;
}
Evo kako bi to trebalo izgledati, varijacija na flokijevu ideju, maksimalno pojednostavljeno.
Znam da nije potrebno 2x otvarati i zatvarati datoteku nego se moze koristiti fseek(), ali sam ga namjerno izostavio da bi kôd bio sto jednostavniji.
Jedino me malo muci spremanje stringa u strukturu, ako netko ima pametniju ideju koja ne ukljucuje sprintf rado bih ju vidio.
Opališ pokazivač:
#include <stdlib.h>
#include <stdio.h>
typedef struct
{
char *tekst;
} struktura;
int main()
{
test.tekst = "Hello Word";
}
Promaklo ti je nesto, iako to radi, ti zapravo ne spremas tekst nego pokazivac (memorijsku adresu, jel). Provjeri sto je doista zapisano u datoteci. Morao bi ici kroz sve elemente strukture i spremati ih zasebno, nekako ovako:
fwrite(&test.a, sizeof(test.a), 1, fh);
fwrite(&test.b, sizeof(test.b), 1, fh);
fwrite(&test.s, sizeof(test.s), 1, fh);
fwrite(test.tekst, strlen(test.tekst), 1, fh);
fwrite(&test.c, sizeof(test.c), 1, fh);
A citanje se zakomplicira jer spremas string varijabilne duljine, pa treba napisati rutinu koja ce se nositi s time pri citanju. Ali svejedno fala, iz tko zna kakvih razloga uopce mi nije palo na pamet trpati const char u pointer :D
Opališ pokazivač:
#include <stdlib.h>
#include <stdio.h>
typedef struct
{
char *tekst;
} struktura;
int main()
{
test.tekst = "Hello Word";
}
Ufff ne znam koliko to prolazi na svim complierima... ovaj = ni ne postoji kao operator na C-ovskim stringovima (odnosno char* )... tu je pridruživanje pointera, kasnije ako se to ide mijenjat ko zna kako bi završilo... tu bih ja ili dinamička alokacija ili staviti char tekst[50] u strukturu, pa sa strcpy ukopirati unutra tekst. Ovo tvoje mi jako pimljavo djeluje..
Radi na GCC kompajleru.
U biti ima to ima smisla zato sto on pointeru daje adresu string literala. Sto se tu zapravo dogada jest obicna operacija s pokazivacima (C ionako definira polja kao pokazivac na prvi element polja). Ovo sam uspio naci na netu (iz C99 standarda 6.4.5/5 "String Literals - Semantics"):
In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals. The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. For character string literals, the array elements have type char, and are initialized with the individual bytes of the multibyte character sequence; for wide string literals, the array elements have type wchar_t, and are initialized with the sequence of wide characters...
It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.
Znaci string literal se pretvara u polje te se adresa dobivenog polja pohranjuje u pokazivac, zasad sve stima. Problem nastaje kod drugog boldanog dijela koji kaze da pokusaj modifikacije takvog polja zavrsava nedefiniranim ponasanjem. Zato bi pokazivac na takav string po nekakvoj logici trebao biti definiran kao const char* da se sprijeci slucajan naknadni pokusaj modifikacije.
Znaci string literal se pretvara u polje te se adresa dobivenog polja pohranjuje u pokazivac, zasad sve stima. Problem nastaje kod drugog boldanog dijela koji kaze da pokusaj modifikacije takvog polja zavrsava nedefiniranim ponasanjem. Zato bi pokazivac na takav string po nekakvoj logici trebao biti definiran kao const char* da se sprijeci slucajan naknadni pokusaj modifikacije.
Znači dobra mi je intuicija :D
Za polja vrijedi aritmetika pokazivača, i nema zapreke da se koriste kad se radi sa char poljima, međutim , ovdje imamo drugi problem, u datoteku se upisuje adresa na koju pokazivač pokazuje, a ne vrijednost na koju pokazivač pokazuje
ostaje strcpy naredba kako je Luka rekao, uz male preinake strukture dobili bi:
#include <stdlib.h>
#include <stdio.h>
#include<string.h>
struct
{
int a;
int b;
char s;
char tekst[25];
float c;
} struktura;
int main()
{
FILE *fh;
//dodaj vrijednosti elementima strukture
struktura.a=50;
struktura.b=480;
struktura.s='x';
strcpy(struktura.tekst, "Hello Word");
struktura.c=3.14;
//otvori datoteku, spremi strukturu, zatvori datoteku
fh=fopen("test.txt", "wb");
fwrite(&struktura, sizeof(struktura), 1, fh);
fclose(fh);
//otvori datoteku, procitaj strukturu, zatvori datoteku
fh=fopen("test.txt", "rb");
fread(&struktura, sizeof(struktura), 1, fh);
fclose(fh);
//ispisi vrijednosti elemenata procitane strukture
printf("%d\n", struktura.a);
printf("%d\n", struktura.b);
printf("%c\n", struktura.s);
printf("%s\n", struktura.tekst);
printf("%1.2f\n", struktura.c);
system("pause");
return 0;
}
Međutim, ovakve stvari se obično unose u strukturu preko konzole, pošto je struktura baš i formirana za to da sadrži više objekata strukture
Za polja vrijedi aritmetika pokazivača, i nema zapreke da se koriste kad se radi sa char poljima, međutim , ovdje imamo drugi problem, u datoteku se upisuje adresa na koju pokazivač pokazuje, a ne vrijednost na koju pokazivač pokazuje
ostaje strcpy naredba kako je Luka rekao, uz male preinake strukture dobili bi:
.
.
.
.
.
Sviđa mi se ovo riješenje. Budem probao.
Za polja vrijedi aritmetika pokazivača, i nema zapreke da se koriste kad se radi sa char poljima, međutim , ovdje imamo drugi problem, u datoteku se upisuje adresa na koju pokazivač pokazuje, a ne vrijednost na koju pokazivač pokazuje
ostaje strcpy naredba kako je Luka rekao, uz male preinake strukture dobili bi:
.
.
.
.
.
Sviđa mi se ovo riješenje. Budem probao.
ti moraš unijeti elemente preko konzole,
dakle:
gets(struktura.tekst);
bit srukture i jest da unosiš podatke više puta, ovo je bio samo ogledni primjerak sa datim vrijednostima u programu
dakle:
gets(struktura.tekst);
bit srukture i jest da unosiš podatke više puta, ovo je bio samo ogledni primjerak sa datim vrijednostima u programu
Uklopit ću onaj program što sam ranije napisao.
Što kažete na ovo:
Napišite program koji učitava broj N koji ne smije biti manji od 3 niti veći do 20
Zatim kreirajte tekstualnu datoteku, pripremite za pisanje i upišite u nju broj N
formatirano.
N puta računajte slijedeće:
- Generirajte slučajni cijeli broj M iz intervala [5, 15].
- Generirajte M cijelih brojeva iz intervala [32,127] i uvrstite ih u dinamički alocirano
polje od M elemenata.
- Upišite u datoteku broj M i polje od M elemenata formatirano u jedan redak (zapis).
- Sve to isto ispisujte na zaslonu monitora.
- Oslobodite memoriju za prethodno alocirano polje.
Nakon toga zatvorite datoteku.
Na kraju izvršenja programa (na primjer, za N = 3) datoteka treba izgledati kao na
primjeru:
3
7 55 53 125 80 68 45 48
8 59 63 90 73 41 113 50 53
5 94 58 78 46 103
Napišite funkciju koja će otvoriti datoteku iz prvog zadatka. Nakon toga treba učitati
sve podatke iz datoteke, na isti način kako su prethodno u njoj zapisani.
Ispisivati na zaslon sve zapise, a nakon učitavanja svih zapisa ispisati redni broj
zapisa s najmanjim zbrojem vrijednosti polja. Na kraju u funkciji zatvoriti datoteku i
vratiti najmanji pronađeni zbroj. Funkciju dodati u program iz prvog zadatka, pozvati
na kraju glavne funkcije i ispisati najmanji zbroj.
Ja sam napravio dio,ali mi se program ruši:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int N;
int i;
int M;
int a;
int polje[a];
srand((unsigned)time(NULL));
do{
printf ("\n Unesite broj izmedu 3 i 20. \n\n");
scanf (" %d",&N);
if (N<3 || N>20) printf ("\n Unijeli ste pogresan broj. \n\n");
}while(N<3 || N>20);
FILE *fh;
fh=fopen("datoteka.txt", "wb");
fwrite(&N, sizeof(N), 1, fh);
for(i=0;i<N;i++){
M=((rand()%9)+5);
fwrite(&M, sizeof(M), 1, fh);
for(a=0;a<M;a++) {
polje[a]=((rand()%85)+32);
}
}
fclose(fh);
system("PAUSE");
return 0;
}
Zasto pises u binarnu datoteku ako ti je eksplicitno zadano da treba biti formatirana ?
umjesto "wb" u fopen() koristi "w" a umjesto fwrite() koristi fprintf() za upis u datoteku.
EDIT:
A zasto ti se rusi? int polje[a]; != dobro, duzina polja mora biti poznata prije pokretanja
programa ako ne mislis dinamicki alocirati memoriju za polje. Ovo sto si napisao nebi nuzno bilo lose
da si varijablu "a" inicijalizirao tako da joj vrijednost nije neodredena (i to doslovno, moze biti bilo sta). Varijable je uvijek dobro
inicijalizirati tj. pridruziti im neku vrijednost (najbolje pri deklaraciji), a varijable koje se koriste unutar
for petlje je kada vec koristis c++ kompajler dobro deklarirati i inicijalizirati pri definiciji petlje, npr:
for(int i = 0; i < BROJ; i++)
Zato što nemam blage što to znači.
E da, znam da vjerojatno kasnim, ali eto nek se nađe. Umjesto fflusha uvijek koristite sljedeći odječak za čišćenje streama:
int char;
while ((char = getchar()) != EOF && char != '\n');
Postoji još par finti, ali ja uglavnom ovo koristim, pa eto nek se nađe.
Krivo radis, kao sto su ti vec rekli, u pitanju je tekstualna datoteka. Ovo sto ti pokusavas je memorijsku vrijednost varijable baciti u datoteku koristeci fwrite, kod integera to ce ti dati 4 necitka hijeroglifa.
Ugl, ovaj zadatak je interesantan zato sto se koristi heap memorija (sada imas priliku rusiti program na nezamislive nove nacine ), a to prevazilazi 99% zadataka koje sam vidio ovdje.
Inace imam neki osjecaj da je ovo polje trebalo drukcije koristiti nego sto sam ga ja. Trebalo je valjda prvo petljom popuniti polje nasumicnim brojevima, pa onda drugom petljom iz prethodno popunjenog polja izvlaciti pojedine elemente i spremati ih na disk. Kako se to meni ne svida, ja sam istovremeno popunjavao polje i spremao elemente na disk. Buduci da si cijeli kôd dobio na pladnju mozes si barem to promijeniti ako ti se ne svida.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int otvori()
{
FILE *fh;
int najmanji_zbroj, trenutni_zbroj, N, M, i, n, najmanji_red, znak;
najmanji_zbroj=2000;
fh=fopen("zadatak.txt", "r");
fscanf(fh, "%d\n", &N);
printf("\n%d", N);
for (i=1; i<=N; i++)
{
trenutni_zbroj=0;
fscanf(fh, "%d ", &M);
printf("\n%d ", M);
for (int n=1; n<=M; n++)
{
fscanf(fh, "%d ", &znak);
trenutni_zbroj+=znak;
printf("%d ", znak);
}
if (trenutni_zbroj<najmanji_zbroj)
{
najmanji_zbroj=trenutni_zbroj;
najmanji_red=i;
}
}
printf("\n\nRed u kojem je najmanji zbroj je: %d", najmanji_red);
fclose(fh);
return najmanji_zbroj;
}
int main()
{
int N, M, i, n;
unsigned char *polje;
FILE *fh;
printf("Unesite broj N: ");
scanf("%d", &N);
while (N<3 || N>20)
{
printf("Unjeli ste pogresan broj.\nUnesite broj N: ");
scanf("%d", &N);
}
srand(time(NULL));
fh=fopen("zadatak.txt", "w");
printf("\n%d", N);
fprintf(fh,"%d", N);
for (i=1; i<=N; i++)
{
M=(rand()%10)+5;
printf("\n%d ", M);
fprintf(fh,"\n%d ", M);
polje=(unsigned char*)malloc(M);
for (n=0; n<M; n++)
{
polje[n]=(rand()%95)+32;
printf("%d ", polje[n]);
fprintf(fh,"%d ", polje[n]);
}
free(polje);
}
fclose(fh);
printf("\n");
printf("\nZbroj brojeva u najmanjem redu iznosi: %d\n\n", otvori());
system("pause");
return 0;
}
pomoću koje funkcije napraviti da program isčitava iz jedne datoteke prvih 40 znakova iz svakog reda. postoji 210 redova i u svakom 138 znakova, a meni treba samo prvih 40. pretposavljam da bi se ti znakovi onda trebali spremati u polje znakova od 40 mjesta. i da kasnije tih 40 znakova ispiše u drugu datoteku, svakih tih 40 znakova u novi red
pomoću koje funkcije napraviti da program isčitava iz jedne datoteke prvih 40 znakova iz svakog reda. postoji 210 redova i u svakom 138 znakova, a meni treba samo prvih 40. pretposavljam da bi se ti znakovi onda trebali spremati u polje znakova od 40 mjesta. i da kasnije tih 40 znakova ispiše u drugu datoteku, svakih tih 40 znakova u novi red
For petlja sa fscanf-om bi trebala riješiti stvar. Za drugi dio fprintf i \n.
pomoću koje funkcije napraviti da program isčitava iz jedne datoteke prvih 40 znakova iz svakog reda. postoji 210 redova i u svakom 138 znakova, a meni treba samo prvih 40. pretposavljam da bi se ti znakovi onda trebali spremati u polje znakova od 40 mjesta. i da kasnije tih 40 znakova ispiše u drugu datoteku, svakih tih 40 znakova u novi red
Za to bih koristio fgets, koji cita liniju po liniju, te bih uzimao samo prvih 40 znakova. Sve bih to spremao u dvodimenzionalno polje dimenzija 41x210.
For petlja sa fscanf-om bi trebala riješiti stvar. Za drugi dio fprintf i \n.
to znam, da, ali kako ide taj kod? znam prototip, ali men to sve nekako čudno ispane pa ne radi
Za to bih koristio fgets, koji cita liniju po liniju, te bih uzimao samo prvih 40 znakova. Sve bih to spremao u dvodimenzionalno polje dimenzija 41x210.
onaj gornji način je prihvatljiviji
Pogledaj primjer što mi je dao Rustweaver. Tamo imaš sve.
Prihvatljiviji u kojem smislu? Evo sto sam nabrzinu sklepao da ti pokazem jednostavnost, prvu petlju ignoriraj to sluzi meni da napravim datoteku sa 210 linija po 138 znakova. Druga petlja cita takvu datoteku i uzima samo prvih 40 znakova, te treca petlja ispisuje to sto je druga petlja napravila.
char *data[210] ti je zapravo polje od 210 pokazivaca na stringove (linije teksta). Da bi ispisao neku liniju teksta samo koristis printf("%s", data[n])
Sve linije drzim na heapu da se smanji koristenje stacka, ali se moze maknuti dinamicka alokacija memorije na nekim mjestima da se jos pojednostavi.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *fh;
char line[139];
char *data[210];
char *buffer;
int i, n;
fh=fopen("test.txt", "w");
for (n=1; n<=210; n++)
{
for (i=0; i<138; i++)
line[i]=(rand()%25)+65;
line[138]=0;
fprintf(fh, "%s\n", line);
}
fclose(fh);
buffer=(char*)malloc(512);
fh=fopen("test.txt", "r");
for (n=0; n<210; n++)
{
fgets(buffer, 140, fh);
data[n]=(char*)calloc(41, 1);
memcpy(data[n], buffer, 40);
}
fclose(fh);
for (n=0; n<210; n++)
printf("%s\n", data[n]);
system("pause");
return 0;
}
Ako ti nesto nije jasno, pitaj. Moguce je napraviti i sa fscanf() kao sto je vexx5555 rekao ali je kompliciranije (bar meni).
tko može reći u čemu je greška ovdje? zašto funckija izracunaj_period ne izračuna dobro period?
spremite ovo u test.txt
2P/Encke |2000|20100806.4951 | 0.335942 |0.848295 |186.5507 |334.5682 | 11.7824 |11.5 |15.0 | MPC 69911
tko može reći u čemu je greška ovdje? zašto funckija izracunaj_period ne izračuna dobro period?
spremite ovo u test.txt
2P/Encke |2000|20100806.4951 | 0.335942 |0.848295 |186.5507 |334.5682 | 11.7824 |11.5 |15.0 | MPC 69911
Zato što računaš period prije nego što si uopće učitao podatke iz datoteke.
Također string učitaj s %39s, a ne %39c.