Diskuze: Zápis do souboru
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
DarkCoder:28.12.2017 20:45
Máš tam 2 chyby:
- Escape sekvence %d se používá pro načtení celého čísla (int). Pokud chceš načíst znak použij funkci getchar(). Funkce getchar() má následující prototyp:
int getchar(void);
a tedy:
char zapis;
zapis = getchar();
- Funkci fprintf() voláš se špatným počtem a typem parametrů. Funkce fprintf() má následující prototyp:
int fprintf(FILE *fp, char *formatovaci_retezec, ...);
a tedy:
FILE *soubor;
int vysledek;
fprintf(soubor, "%d", vysledek);
Martin Dráb:28.12.2017 20:48
¨Pro tyto účely tu existuje funkce fwrite.
fwrite(&vysledek, sizeof(vysledek), 1, soubor);
Parametry:
- adresa dat, která chci zapsat,
- velikost jednoho elementu dat,
- počet elementů k zapásní (vhodné v případě, že zapisuješ pole),
- adresa struktury FILE * popisující soubor, kam zapisuješ.
Součin druhého a třetího parametru udává počet bajtů, které budou zapsány počínaje adresou předanou v prvním parametru. Čtvrý parametr získáš např. funkcí foepn, nebo můžeš použít standardní výstup (stdout) či standardní chybový výstup (stderr).
Jen POZOR na to, že ve Windows se rozlišuje binární a textový přístup k souboru (protože konce řádků jsou kódovány dvěma znaky a soubor otevřený v textovém režimu je sám "opravuje"). Pokud chceš zapisovat binární data (což zjevně chceš), musíš buď soubor otevřít v binárním režimu (přidej znak b do druhého parametru fopen, nebo použij funkci _setmode pro nastavení režimu již otevřeného souboru (platí zejména pro stdout a stderr). Tahle chyba je velmi nebezpečná a velmi těžko se zpětně hledá.
Ahoj, díky za info. Poupravil jsem to a vypadá to takto. Jen mi to vždycky rovnou zapíše do souboru a neptá se to zda chci zapsat. Do txt mi to vypíše buďto nějaký znaky a nebo nic.
Jsem v tom úplně na začátcích, tak se omlouvám že to je se mnou takový těžší.
#define _CRT_SECURE_NO_WARNINGS
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define PI 3.14159265359
#define textak "text.txt"
int main(int argc, char *argv[]) {
int operator;
int prvnicislo;
int druhecislo;
char zapis;
FILE *soubor; // When working with files, you need to declare a pointer of type file. This declaration is needed for communication between the file and program.
soubor = fopen(textak, "a+"); // Open for reading and appending (writing at end of file). The file is created if it does not exist. The initial file position for reading is at the beginning of the file, but output is always appended to the end of the file.
/*
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
*/
printf("\nMENU OPERACI\n\n");
printf("1 pro scitani\n");
printf("2 pro odecitani\n");
printf("3 pro nasobeni\n");
printf("4 pro deleni\n");
printf("5 pro sinus\n");
printf("6 pro cosinus\n");
printf("7 pro tangens\n");
printf("8 pro druhou mocninu\n");
printf("9 pro faktorial");
printf("Q pro ukonceni programu\n\n");
printf("Vyber operaci: ");
scanf("%d", &operator);
do
{
switch (operator) {
case 1:
printf("Zadej prvni cislo: ");
scanf("%d", &prvnicislo);
printf("Zadej druhe cislo: ");
scanf("%d", &druhecislo);
printf("Vysledek: %d\n", prvnicislo + druhecislo);
int vysledek = prvnicislo + druhecislo;
printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
//scanf("%d", &zapis);
zapis = getchar();
if (zapis == 'Y'); // neni case sensitive
{
printf("Zapisuji...\n");
fprintf(soubor, "%d", vysledek);
}
break;
Pokud chceš zapsat to číslo do souboru textově (tzn. aby jsi jej byl jako člověk schopen přečíst, když si ten soubor otevřeš např. v textovém editoru), tak se řiď příspěvkem od DarkCoder. Já jsem řešil případ, kdy to číslo tam chceš zapsat binárně (ve strojově čitelné/binární podobě).
DarkCoder:28.12.2017 23:50
Ve vstupním bufferu Ti zůstávají znaky které funkce getchar() přebírá. Uprav kód na následující:
fseek(stdin, 0, SEEK_END);
zapis = getchar();
if ((zapis == 'Y') || (zapis == 'y')){
printf("Zapisuji...\n");
fprintf(soubor, "%d\n", vysledek);
}
break;
Pozor na ten středník za výrazem v podmínce, to co vytváříš je prázdný příkaz a následující blok už do cíle podmínky nepatří a provede se vždy. Pro ukončení programu zvol 0 (nulu), znakovou konstantu Q proměnná operator nepřevezme.
Ahoj, díky za info. Program funguje ale zapíše mi to zase nějaké znaky. Když sčítám třeba 50 + 50, tak mi to do txt uloží "〱ര".
#define _CRT_SECURE_NO_WARNINGS
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define PI 3.14159265359
#define textak "text.txt"
int main(int argc, char *argv[]) {
int operator;
int prvnicislo;
int druhecislo;
char zapis;
FILE *soubor; // When working with files, you need to declare a pointer of type file. This declaration is needed for communication between the file and program.
soubor = fopen(textak, "a+"); // Open for reading and appending (writing at end of file). The file is created if it does not exist. The initial file position for reading is at the beginning of the file, but output is always appended to the end of the file.
/*
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
*/
printf("\nMENU OPERACI\n\n");
printf("1 pro scitani\n");
printf("2 pro odecitani\n");
printf("3 pro nasobeni\n");
printf("4 pro deleni\n");
printf("5 pro sinus\n");
printf("6 pro cosinus\n");
printf("7 pro tangens\n");
printf("8 pro druhou mocninu\n");
printf("9 pro faktorial\n");
printf("0 pro ukonceni programu\n\n");
printf("Vyber operaci: ");
scanf("%d", &operator);
do
{
switch (operator) {
case 1:
printf("Zadej prvni cislo: ");
scanf("%d", &prvnicislo);
printf("Zadej druhe cislo: ");
scanf("%d", &druhecislo);
printf("Vysledek: %d\n", prvnicislo + druhecislo);
int vysledek = prvnicislo + druhecislo;
printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
//scanf("%d", &zapis);
fseek(stdin, 0, SEEK_END);
zapis = getchar();
if ((zapis == 'Y') || (zapis == 'y')) // neni case sensitive
{
printf("Zapisuji...\n");
fprintf(soubor, "%d\n", vysledek);
}
break;
case 2:
printf("Zadej prvni cislo: ");
scanf("%d", &prvnicislo);
printf("Zadej druhe cislo: ");
scanf("%d", &druhecislo);
printf("Vysledek: %d\n", prvnicislo - druhecislo);
break;
case 3:
printf("Zadej prvni cislo: ");
scanf("%d", &prvnicislo);
printf("Zadej druhe cislo: ");
scanf("%d", &druhecislo);
printf("Vysledek: %d\n", prvnicislo * druhecislo);
break;
case 4:
printf("Zadej prvni cislo: ");
scanf("%d", &prvnicislo);
printf("Zadej druhe cislo: ");
scanf("%d", &druhecislo);
printf("Vysledek: %d\n", prvnicislo / druhecislo);
break;
case 5:
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
printf("Vysledek: %f\n", sin(prvnicislo * PI / 180));
break;
case 6:
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
printf("Vysledek: %f\n", cos(prvnicislo * PI / 180));
break;
case 7:
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
printf("Vysledek: %f\n", tan(prvnicislo * PI / 180));
break;
case 8:
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
printf("Vysledek: %d\n", prvnicislo * prvnicislo);
break;
default:
exit(0);
}
return 0;
}
while (operator!='0');
}
DarkCoder:29.12.2017 18:04
Je dobře že jsi sem přiložil celý kód. Pojďme si postupně projít to nejdůležitější.
V předchozích příspěvcích jsem se o tom nezmiňoval, ale vždy testuj funkci fopen() na její návratovou hodnotu. Je to důležité. Je třeba vědět, zda-li se Ti podařilo soubor v daném režimu otevřít.
do-while cyklus není správně ze tří důvodů. Ten první je, že na test jeho podmínky totiž nikdy nedojde. Program ukončuješ buďto v případě, kdy uživatel zadává vstup jiný nežli tebou požadovaný vstup z menu (exit()) nebo po provedení úseku kódu dle volby menu (return). Ten druhý je ten, že je třeba testovat na číselnou hodnotu nikoli znakovou (operator je typu int nikoli char). Ten třetí je že nejspíš chceš, aby si uživatel mohl vybrat novou operaci dle menu po provedení předchozí operace a to zde chybí.
V příkazu switch musíš oddělit dva stavy. Vyhodnocení dle menu a to co do menu nezapadá (case 0-9 a default). case 1-9 obsahuje průběh operace dle menu, case 0 korektní ukončení do-while cyklu.
Např:
case 0: operator = 0;
break;
sekce default by měla obsahovat informaci o neznámém vstupu a vrátit se do menu než tiše ukončit program pomocí exit(). Funkci exit() používej v situaci kdy nastane nějaká abnormální chyba. Jako parametr používej nenulovou hodnotu v závislosti na závažnosti chyby. Využiješ ji třeba při testování správnosti otevření souboru v daném režimu.
Příkaz return s návratovou hodnotou nula umísti před uzavírací složené závorky funkce main(), kterou máš deklarovanou s návratovým typem int. Tím říkáš operačnímu systému, že program skončil bez chyb.
Ale to nejpodstatnější je, že si zapomněl na uzavření souboru. Soubor
uzavřeš pomocí funkce fclose().
Funkce fclose() má následující prototyp:
int fclose(FILE *fp);
a tedy ve tvém případě je třeba za do-while cyklus vložit:
fclose(soubor);
A stejně jako u fopen() můžeš ověřit, zda uzavření souboru proběhlo v pořádku či nikoli.
DarkCoder:29.12.2017 23:04
Uprav test podmínky do-while cyklu z:
while (operator!='0');
Zde porovnáváš se znakovou konstantou.
na:
while (operator!=0);
Zde porovnáváš s celočíselnou konstantou.
popřípadě:
while (operator); // není nula
Což je totožný zápis jako výše uvedený.
Pokud by si to nechal tak jak to bylo, porovnával by si ve skutečnosti proměnnou operator s hodnotou 48 (ASCII kód '0' je 48(DEC)).
DarkCoder:30.12.2017 12:43
Spusť následující kód:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(int argc, char *argv[]) {
FILE *soubor = fopen("test2.txt", "a+");
fprintf(soubor, "%d\n", 50+50);
fclose(soubor);
return 0;
}
Co obsahuje soubor test2.txt?
DarkCoder:30.12.2017 13:05
Správně. Teď spusť následující kód:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(int argc, char *argv[]) {
FILE *soubor = fopen("test2.txt", "a+");
int prvnicislo;
int druhecislo;
int vysledek;
printf("Zadej prvni cislo: ");
scanf("%d", &prvnicislo);
printf("Zadej druhe cislo: ");
scanf("%d", &druhecislo);
printf("Vysledek: %d\n", (vysledek = prvnicislo + druhecislo));
printf("Zapisuji...\n");
fprintf(soubor, "%d\n", vysledek);
fclose(soubor);
return 0;
}
Co se Ti zapsalo do souboru?
Mohlo by to byt tim ze tam misto
FILE *soubor = fopen("test2.txt", "a+");
mám toto?
soubor = fopen(textak, "a+");
Víc mě toho nenapadá. Celý kód teď vypadá takto:
#define _CRT_SECURE_NO_WARNINGS
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define PI 3.14159265359
#define textak "text.txt"
int main(int argc, char *argv[]) {
int operator;
int prvnicislo;
int druhecislo;
//double faktorial;
long vysledek;
char zapis;
unsigned long long faktorial = 1;
int i, n;
FILE *soubor; // When working with files, you need to declare a pointer of type file. This declaration is needed for communication between the file and program.
soubor = fopen(textak, "a+"); // Open for reading and appending (writing at end of file). The file is created if it does not exist. The initial file position for reading is at the beginning of the file, but output is always appended to the end of the file.
/*
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
*/
printf("\nMENU OPERACI\n\n");
printf("1 pro scitani\n");
printf("2 pro odcitani\n");
printf("3 pro nasobeni\n");
printf("4 pro deleni\n");
printf("5 pro sinus\n");
printf("6 pro cosinus\n");
printf("7 pro tangens\n");
printf("8 pro druhou mocninu\n");
printf("9 pro faktorial\n");
printf("10 pro obvod kruhu\n");
printf("11 pro obsah kruhu\n");
printf("0 pro ukonceni programu\n\n");
printf("Vyber operaci: ");
scanf("%d", &operator);
do
{
switch (operator) {
case 1: // scitani
printf("Zadej prvni cislo: ");
scanf("%d", &prvnicislo);
printf("Zadej druhe cislo: ");
scanf("%d", &druhecislo);
vysledek = prvnicislo + druhecislo;
printf("Vysledek: %d\n", vysledek);
printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
//scanf("%d", &zapis);
fseek(stdin, 0, SEEK_END);
zapis = getchar();
if ((zapis == 'Y') || (zapis == 'y'))
{
printf("Zapisuji...\n");
fprintf(soubor, "%d\n", vysledek);
}
break;
case 2: // odcitani
printf("Zadej prvni cislo: ");
scanf("%d", &prvnicislo);
printf("Zadej druhe cislo: ");
scanf("%d", &druhecislo);
vysledek = prvnicislo - druhecislo;
printf("Vysledek: %d\n", vysledek);
printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
fseek(stdin, 0, SEEK_END);
zapis = getchar();
if ((zapis == 'Y') || (zapis == 'y'))
{
printf("Zapisuji...\n");
fprintf(soubor, "%d\n", vysledek);
}
break;
case 3: // nasobeni
printf("Zadej prvni cislo: ");
scanf("%d", &prvnicislo);
printf("Zadej druhe cislo: ");
scanf("%d", &druhecislo);
vysledek = prvnicislo * druhecislo;
printf("Vysledek: %d\n", vysledek);
printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
fseek(stdin, 0, SEEK_END);
zapis = getchar();
if ((zapis == 'Y') || (zapis == 'y'))
{
printf("Zapisuji...\n");
fprintf(soubor, "%d\n", vysledek);
}
break;
case 4: // deleni
printf("Zadej prvni cislo: ");
scanf("%d", &prvnicislo);
printf("Zadej druhe cislo: ");
scanf("%d", &druhecislo);
vysledek = prvnicislo / druhecislo;
printf("Vysledek: %d\n", vysledek);
printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
fseek(stdin, 0, SEEK_END);
zapis = getchar();
if ((zapis == 'Y') || (zapis == 'y'))
{
printf("Zapisuji...\n");
fprintf(soubor, "%d\n", vysledek);
}
break;
case 5: // sinus
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
printf("Vysledek: %f\n", sin(prvnicislo * PI / 180));
break;
case 6: // cosinus
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
printf("Vysledek: %f\n", cos(prvnicislo * PI / 180));
break;
case 7: // tangens
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
printf("Vysledek: %f\n", tan(prvnicislo * PI / 180));
break;
case 8: // druha mocnina
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
printf("Vysledek: %d\n", prvnicislo * prvnicislo);
break;
case 9: // faktorial
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
if (prvnicislo < 0)
{
printf("Faktorial nelze pro zaporne cislo spocitat\n");
return 0;
}
else
{
for (int i = 1; i <= prvnicislo; ++i)
{
faktorial *= i; // faktorial = faktorial * i;
}
printf("Faktorial cisla %d je %llu\n", prvnicislo, faktorial);
}
printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
fseek(stdin, 0, SEEK_END);
zapis = getchar();
if ((zapis == 'Y') || (zapis == 'y'))
{
printf("Zapisuji...\n");
fprintf(soubor, "%d, %llu\n", prvnicislo, faktorial);
}
break;
case 10: // obvod kruhu
printf("Zadej polomer: ");
scanf("%d", &prvnicislo);
if (prvnicislo < 0)
{
printf("Obvod nelze pro zaporne cislo spocitat\n");
return 0;
}
else
{
vysledek = 2 * PI * prvnicislo;
}
printf("Vysledek: %d\n", vysledek);
printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
fseek(stdin, 0, SEEK_END);
zapis = getchar();
if ((zapis == 'Y') || (zapis == 'y'))
{
printf("Zapisuji...\n");
fprintf(soubor, "%d\n", vysledek);
}
break;
case 11: // obsah kruhu
break;
case 0:
operator = 0;
break;
/*default: // vhodnejsi pouzit case 0...
exit(0);*/
}
fclose(soubor);
return 0;
}
while (operator!=0);
return(0);
}
DarkCoder:30.12.2017 13:21
Spusť následující kód:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(int argc, char *argv[]) {
FILE *soubor = fopen("test2.txt", "a+");
int prvnicislo;
int druhecislo;
int vysledek;
int operator;
do {
printf("MENU OPERACI\n");
printf("1 pro scitani\n");
printf("0 pro ukonceni programu\n\n");
printf("Vyber operaci: ");
scanf("%d", &operator);
switch (operator) {
case 0: break;
case 1: printf("Zadej prvni cislo: ");
scanf("%d", &prvnicislo);
printf("Zadej druhe cislo: ");
scanf("%d", &druhecislo);
printf("Vysledek: %d\n", (vysledek = prvnicislo + druhecislo));
printf("Zapisuji...\n\n");
fprintf(soubor, "%d\n", vysledek);
break;
default: printf("Neznama operace.\n\n");
break;
}
} while (operator);
fclose(soubor);
return 0;
}
Já se zatím podívám na tvůj kód...
DarkCoder:30.12.2017 13:39
Pokud používáš proměnnou typu long, používej specifikátor %ld.
Soubor uzavírej až za do-while cyklem a odstraň řádek s return 0 uvnitř
cyklu.
...
case 0: break;
default: printf("Neznama operace.\n\n");
break;
} // switch
} while (operator!=0); // do-while
fclose(soubor);
return(0);
} // main
Ahoj, upravil jsem to, ale teď mi to tam vůbec nic nezapíše
#define _CRT_SECURE_NO_WARNINGS
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define PI 3.14159265359
#define textak "text.txt"
int main(int argc, char *argv[]) {
int operator;
int prvnicislo;
int druhecislo;
//double faktorial;
long vysledek;
char zapis;
unsigned long long faktorial = 1;
int i, n;
FILE *soubor; // When working with files, you need to declare a pointer of type file. This declaration is needed for communication between the file and program.
soubor = fopen(textak, "a+"); // Open for reading and appending (writing at end of file). The file is created if it does not exist. The initial file position for reading is at the beginning of the file, but output is always appended to the end of the file.
/*
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
*/
printf("\nMENU OPERACI\n\n");
printf("1 pro scitani\n");
printf("2 pro odcitani\n");
printf("3 pro nasobeni\n");
printf("4 pro deleni\n");
printf("5 pro sinus\n");
printf("6 pro cosinus\n");
printf("7 pro tangens\n");
printf("8 pro druhou mocninu\n");
printf("9 pro faktorial\n");
printf("10 pro obvod kruhu\n");
printf("11 pro obsah kruhu\n");
printf("0 pro ukonceni programu\n\n");
printf("Vyber operaci: ");
scanf("%d", &operator);
do
{
switch (operator)
{
case 1: // scitani
printf("Zadej prvni cislo: ");
scanf("%d", &prvnicislo);
printf("Zadej druhe cislo: ");
scanf("%d", &druhecislo);
vysledek = prvnicislo + druhecislo;
printf("Vysledek: %d\n", vysledek);
printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
//scanf("%d", &zapis);
fseek(stdin, 0, SEEK_END);
zapis = getchar();
if ((zapis == 'Y') || (zapis == 'y'))
{
printf("Zapisuji...\n");
fprintf(soubor, "%d\n", vysledek);
}
break;
case 2: // odcitani
printf("Zadej prvni cislo: ");
scanf("%d", &prvnicislo);
printf("Zadej druhe cislo: ");
scanf("%d", &druhecislo);
vysledek = prvnicislo - druhecislo;
printf("Vysledek: %d\n", vysledek);
printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
fseek(stdin, 0, SEEK_END);
zapis = getchar();
if ((zapis == 'Y') || (zapis == 'y'))
{
printf("Zapisuji...\n");
fprintf(soubor, "%d\n", vysledek);
}
break;
case 3: // nasobeni
printf("Zadej prvni cislo: ");
scanf("%d", &prvnicislo);
printf("Zadej druhe cislo: ");
scanf("%d", &druhecislo);
vysledek = prvnicislo * druhecislo;
printf("Vysledek: %d\n", vysledek);
printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
fseek(stdin, 0, SEEK_END);
zapis = getchar();
if ((zapis == 'Y') || (zapis == 'y'))
{
printf("Zapisuji...\n");
fprintf(soubor, "%d\n", vysledek);
}
break;
case 4: // deleni
printf("Zadej prvni cislo: ");
scanf("%d", &prvnicislo);
printf("Zadej druhe cislo: ");
scanf("%d", &druhecislo);
vysledek = prvnicislo / druhecislo;
printf("Vysledek: %d\n", vysledek);
printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
fseek(stdin, 0, SEEK_END);
zapis = getchar();
if ((zapis == 'Y') || (zapis == 'y'))
{
printf("Zapisuji...\n");
fprintf(soubor, "%d\n", vysledek);
}
break;
case 5: // sinus
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
printf("Vysledek: %f\n", sin(prvnicislo * PI / 180));
break;
case 6: // cosinus
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
printf("Vysledek: %f\n", cos(prvnicislo * PI / 180));
break;
case 7: // tangens
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
printf("Vysledek: %f\n", tan(prvnicislo * PI / 180));
break;
case 8: // druha mocnina
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
printf("Vysledek: %d\n", prvnicislo * prvnicislo);
break;
case 9: // faktorial
printf("Zadej cislo: ");
scanf("%d", &prvnicislo);
if (prvnicislo < 0)
{
printf("Faktorial nelze pro zaporne cislo spocitat\n");
return 0;
}
else
{
for (int i = 1; i <= prvnicislo; ++i)
{
faktorial *= i; // faktorial = faktorial * i;
}
printf("Faktorial cisla %d je %llu\n", prvnicislo, faktorial);
}
printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
fseek(stdin, 0, SEEK_END);
zapis = getchar();
if ((zapis == 'Y') || (zapis == 'y'))
{
printf("Zapisuji...\n");
fprintf(soubor, "%d, %llu\n", prvnicislo, faktorial);
}
break;
case 10: // obvod kruhu
printf("Zadej polomer: ");
scanf("%d", &prvnicislo);
if (prvnicislo < 0)
{
printf("Obvod nelze pro zaporne cislo spocitat\n");
return 0;
}
else
{
vysledek = 2 * PI * prvnicislo;
}
printf("Vysledek: %d\n", vysledek);
printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
fseek(stdin, 0, SEEK_END);
zapis = getchar();
if ((zapis == 'Y') || (zapis == 'y'))
{
printf("Zapisuji...\n");
fprintf(soubor, "%d\n", vysledek);
}
break;
case 11: // obsah kruhu
break;
case 0:
operator = 0;
break;
default:
printf("Neznama operace\n");
break;
}
}
while (operator!=0);
fclose(soubor);
return (0);
}
DarkCoder:30.12.2017 14:24
Jinač všechny následující úryvky kódu jsou výsledkově totožné
FILE *soubor = fopen("test2.txt", "a+");
FILE *soubor;
soubor = fopen("test2.txt", "a+");
#define textak "test2.txt"
FILE *soubor = fopen(textak, "a+");
#define textak "test2.txt"
FILE *soubor;
soubor = fopen(textak, "a+");
DarkCoder:30.12.2017 14:33
Ahoj, upravil jsem to, ale teď mi to tam vůbec nic nezapíše
Program musíš řádně ukončit, bez toho se Ti do souboru nic nezapíše. Musíš kód upravit tak, aby se dal ukončit. Všimni si, že jsem vložil menu do těla do-while cyklu. Důvodem je abych mohl vybrat novou operaci nebo ukončit program.
DarkCoder:30.12.2017 14:57
Podívej na následující kód:
do {
printf("Zadej cislo: ");
scanf("%d", &operator);
// ...
} while (operator);
Na stejném principu musíš upravit svůj program.
Ahoj,
tak už to mám a dokonce mi to i vypisuje čísla a ne znaky, tak super
Děkuju ti moc!!
Ještě mám poslední dotaz. Jsou nějaké výhody / nevýhody mezi těmito
zápisy, jak jsi psal prve?
FILE *soubor = fopen("test2.txt", "a+");
FILE *soubor;
soubor = fopen("test2.txt", "a+");
#define textak "test2.txt"
FILE *soubor = fopen(textak, "a+");
#define textak "test2.txt"
FILE *soubor;
soubor = fopen(textak, "a+");
Pro moje potřeby se mi jeví nejjednodušší používat ten první řádek.
FILE *soubor = fopen("test2.txt", "a+");
DarkCoder:30.12.2017 17:57
Tak to je skvělé. Takže už víš kde byla chyba? Doposud jsem se nezabýval ostatními operacemi ve tvém programu. Teď nastal čas a věřím že Tě potěším, když Ti sdělím, že bys teď se mohl zbavit toho duplicitního kódu v příkazu switch.
Jsou nějaké výhody / nevýhody mezi těmito zápisy, jak jsi psal prve?
Pokud víš, že jméno souboru budeš používat na více místech v programu, je dobré používat direktivu preprocesoru #define. Kdyby si chtěl jméno souboru změnit, stačí ho změnit na jednom místě a všechny ostatní odkazy se změní, čímž se můžeš vyhnout chybám souborového systému (a nejen jeho), zejména pokud neděláš ošetření na vrácenou hodnotu. Zde je vidět, proč je třeba tuto hodnotu testovat.
Pokud víš, s jakým souborem budeš pracovat, můžeš ukazatel na soubor inicializovat. Je to ten řádek, který se Ti jeví jako nejjednodušší. Navíc Ti to ušetří trochu psaní textu.
V komplexnějších aplikacích, kde pracuješ s více soubory a kde použitý soubor přiřazuješ až v průběhu na základě nějakých informací, používáš poslední variantu. Tu bych jen z důvodu bezpečnosti trochu rozšířil na následující:
FILE *soubor = NULL;
soubor = fopen("test.txt", "a+");
Je dobré všechny ukazatelové proměnné, které na nic neukazují, takto přiznačit.
Ještě jedna věc. Otevřené soubory, se kterými nepracuješ, zavírej. Jsou pro to minimálně dva důvody. Ten první je že uživatel je omezen množstvím otevřených souborů v jednu chvíli. Ten druhý v okamžiku havárie programu bys mohl nenávratně přijít o spoustu důležitých dat.
+20 Zkušeností
+2,50 Kč
Ahoj, ono to zkracování je teď spíš trochu kontra. Mám to ke zkoušce a
měl bych mít správně 1500 řádků Mám ještě co dělat, abych to dohnal i když se svýma schopnostma
se k tomu asi ani nepřiblížim... Developer ze mě holt nebude
Budu tam muset ještě dodělat spoustu dalších matematických operací.
Každopádně ti děkuju moc za tvůj čas !
Až se zase někde totálně zaseknu tak zkusím zaspamovat znovu, ono to moc
dlouho nepotrvá.
Pěkný zbytek dne.
Jirka:30.12.2017 20:42
Ahoj, co prosím ještě dělá
fseek(stdin, 0, SEEK_END);
Vygooglil jsem že stdin je standard input, tedy klávesnice.
0 bohužel netuším a SEEK_END zařídí, aby se zapsalo na konec souboru?
Děkuju
DarkCoder:30.12.2017 22:00
Toto je úloha kde se dá toho opravdu dost vymyslet a bez problému 1500 řádek kódu napsat. Pokud je profesor trochu pozorný a znalý, tak by Ti to rozhodně vytknul. Pokud těch operací budeš mít dost, což asi budeš, kde každá bude vracet výsledek, pak duplicita by byla do očí bijící a nedělalo by to vůbec dobrý dojem.
Pomocí funkce fseek() lze přistupovat k libovlnému místu v souboru. Její prototyp je:
int fseek(FILE * fp, long posun, int pocatek);
stdin je standartní vstup, což je jeden z datových proudů, který je otevřen při spuštění programu. Není to klávesnice, ta je souborem. Standartní datové proudy jsou ukazatele na FILE a mohou být použity tam kde se pracuje s proměnnou typu FILE *.
Parametr pocatek musí být jedním z maker SEEK_SET, SEEK_CUR nebo SEEK_END. Jejich význam je počátek souboru, aktuální pozice v souboru a konec souboru. Parametr posun udává počet bytů od počátku.
A tedy:
fseek(stdin, 0L, SEEK_END);
způsobí nastavení aktuální pozice standartního vstupu na konec a přeskočí tak všechny čekající znaky. Doplněné L ve druhém parametru je z důvodu přebrání správného typu (long).
Nechybí tam vyprázdnění vyrovnávací paměti pomoci fflush(); , když to
je výstupní proud??
(já si myslím, že by to tam mělo být).
DarkCoder:31.12.2017 3:15
Při spuštění programu jsou automaticky otevřeny a připraveny k použití tři datové proudy. Jedná se o standardní vstup (stdin), standardní výstup (stdout) a standardní chyba (stderr). Dále je připojen mezi soubory (klávesnice a diskový soubor) textový datový proud pomocí funkce fopen(). Odpojení datového proudu se provádí a je provedeno pomocí funkce fclose(). Vyprázdnění bufferu se uskutečňuje při vyvolání funkce fclose(), kdy se zapíší na disk automaticky všechna data zbývající v bufferu. Standardní datové proudy jsou obsluhovány interně překladačem, nelze pro ně používat funkce fopen() a fclose() a nesmí se měnit. Pokud datový proud sami neuzavřeme, je automaticky uzavřen po řádném skončení programu. Je ale dobrým zvykem vyprazdňovat vyrovnávací paměť na důležitých místech pomocí fflush(stdout) popř. fflush(NULL).
Zobrazeno 31 zpráv z 31.