#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#define bemenetnev "minta.csv" //Saját .csv file készítésénél figyeljünk a megfelelő mentésre: Excelben pontosvesszővel tagoltként mentsük, különben
#define kimenetnev "kimenet.csv" //a BOM (Byte Order Mark) miatt az első sor előtt lesz egy számunka értelmezhetetlen hexadecimális minta ami a kódolást jelenti.
#define inputnev "input.txt"
#define outputnev "output.txt"
FILE *be, *ki; //A bemeneti és kimeneti fájlok mutatói
int main(void) {
setlocale(LC_ALL, "hu_HU");
//char* str = "0,01";
//char* endptr;
//double val = strtod(str, &endptr);
int sorszam=0;
double elso, masodik, harmadik;
char* buffer = (char*)malloc(100), * mutato, * kovetkezo;
if (buffer == NULL) {
printf("Memória foglalási hiba!\n");
return -1;
}
//.csv file beolvasás rész
fopen_s(&be, bemenetnev, "r");
if (!be) { //Ha a fájl nem nyitható meg (NULL pointer)
printf("Nem található a következő file: %s\n", bemenetnev);
free(buffer);
return -1;
}
fopen_s(&ki, kimenetnev, "w");
if (!ki) {
printf("Nem sikerult a következő filet elkesziteni: %s\n", kimenetnev);
return -1;
}
while (!feof(be)) {
memset(buffer, 0, 100); //buffert kinullázzuk
fgets(buffer, 100, be); //\n-ig olvasás --> Egy sor.
mutato = strtok_s(buffer, ";", &kovetkezo); //Első hívás (soron belül) a ; karaktert a stringben \0-ra felülírja
if (mutato == NULL) break; //Nullpointer kezelés,
//break utasítás megszakítja a ciklust
elso = atof(mutato); //Első adat konvertálása
printf("Elso szam: %lf ", elso);
mutato = strtok_s(NULL, ";", &kovetkezo); //Első hívás után NULL-al, hogy a \0-tól olvassa tovább
masodik = atof(mutato);
printf("Masodik szam: %lf ", masodik);
mutato = strtok_s(NULL, ";", &kovetkezo);
harmadik = atof(mutato);
printf("Harmadik szam: %lf \n", harmadik);
elso *= 100;
masodik *= 1000;
harmadik *= 10000;
fprintf(ki, "%lf;%lf;%lf\n",
elso, masodik, harmadik); //Kimeneti fileba írás
sorszam++;
}
printf("A file %i db sorból állt.\n\n", sorszam);
sorszam = 0;
//.txt file beolvasás rész
fopen_s(&be, inputnev, "r");
if (!be) {
printf("Nem található a következő file: %s\n", bemenetnev);
free(buffer);
return -1;
}
while (!feof(be)) {
memset(buffer, 0, 100);
fgets(buffer, 100, be);
sorszam++;
}
printf("A második file %i db sorból állt.\n\n", sorszam);
fseek(be, 0, SEEK_SET);
int leghosszabb = 0, betelt = 0;
char leghosszabb_szo[100] = "";
for (int i = 0; i < sorszam; i++) { //for és while ciklus egymásba alakítható, a rossz példa kedvéért ezt forral csináljuk, while-al praktikus aminek argumentumában a token állapota van.
fgets(buffer, 100, be);
if (strlen(buffer) == 99) betelt = 1; //Ellenőrzés, hogy a sor befér-e egyáltalán a bufferbe.
else betelt = 0; //Egy .txt elméletileg tartalmazhatna végtelen sok karaktert \n nélkül.
//Teljes file beolvasás NULL pointert adhat ilyen esetekbe - "halálfejes" hiba
mutato = strtok_s(buffer, " ", &kovetkezo); //Szokásos első hívás, most szóközönként fogunk tokenizálni
//Leghosszabb szó keresése rész
leghosszabb = strlen(mutato); //Logika: első \0 token előtti szót defaultban vegyük leghosszabbnak, ha van hosszabb akkor átállítjuk később - Szélsőértékhelykeresés logikája
strcpy_s(leghosszabb_szo,100, mutato); //Nézzük meg debuggal mi történik ha 100 helyett pl. önkényesen 50-et írok ide
//i változó értéke megváltozik valami furcsa értékre, memóriaterületek "összemosódnak"
while (1) { //Buta megoldás, de működőképes, lehetne pl. feltételbe magát a tokenizáló fv.-t vagy annak státuszát kezelő változót beleírni,
mutato = strtok_s(NULL, " ", &kovetkezo);
if (mutato == NULL) break; //Az egész soron végigiterálunk, ha vége a sornak a fv. NULL-t dob, kilépünk a while-ból.
if (strlen(mutato) > strlen(leghosszabb_szo)) {
strcpy_s(leghosszabb_szo,100, mutato);
}
}
if (leghosszabb_szo[0] == '\n') { //Ha a sor csak egy \n karakterből áll
printf("A/az %i sor egy üres sor.\n", i);
continue; //A for ciklust a következő sortól folytassuk, ne is vizsgáljuk tovább ezt követően
}
if (mutato = strchr(leghosszabb_szo, '\n')) { //Minden sor végén van egy \n karakter, ha bennehagyjuk a stringbe és kiiratjuk, a konzolon is egy újsort beletesz.
*mutato = '\0';
}
if (!betelt && leghosszabb_szo[0] != '\n') { //A második feltétel csak szimbolikus, lásd előző felétel.
printf("A leghosszabb szó a/az %i. sorban a %s volt.\n", i, leghosszabb_szo);
}
if (betelt) {
printf("A/az %i. sor nem fért bele a bufferbe. Folytatás következő sor(ok)ban.\n", i);
}
}
fopen_s(&ki, outputnev, "w");
if (!ki) {
printf("Nem sikerült a következő fájlt elérni: %s\n", outputnev);
return -1;
}
fseek(be, 0, SEEK_SET);
while (fgets(buffer, 100, be)) { //A fgets közvetlenül kezeli a fájl végét, nem kell !feof
//Ha a beolvasott sor pontosan 6 karakter hosszú (figyeljünk az új sor karakterre is)
if (strlen(buffer) == 7 && buffer[strlen(buffer) - 1] == '\n') {
buffer[strlen(buffer) - 1] = '\0'; //Az új sort eltávolítjuk
fprintf(ki, "%s\n", buffer); //Kiírjuk a kimeneti fájlba
}
}
free(buffer);
return 0;
}
//Gyakorló feladatok - Tetszés szerint Joe ujadat fv.-el is és strtok-kal is egyaránt elfogadható egy-egy megoldás.
//1. Feladat
//Készítsünk egy .txt fájl amelyben tetszőleges, tetszőleges számú egész szám szerepel soronként.
//a) Dolgozzuk fel úgy, hogy kinyerjük belőle a legtöbb 1-es számjegyet tartalmazó számot
//b) Minden egyes sorban kétszerezzük meg a számokat egy külön fileba beleírva
//c) Ezen felül változtassunk minden számot negatívvá
//d) A nullás számjegyeket cseréljük 'o' betűkre
//
//2. Feladat
//Egy nagyon hosszú egy soros filet 20 karakterenként tördeljük újsorokkal.
//Egy könyvből kimásolt részletet tördeljünk mondatonként ha a mondat hossza 30 és 40 karakter közötti, (a végjellel együtt)
//Ha hosszabb mint 40 karakter, 38karakterenként adjunk hozzá egy kötőjelet és \n-t.
//
//3.Feladat
//Írj egy primitív - szavakat elválasztó programot, elválasztások kezeléséhez:
//1) két egymást követő mássalhangzó esetén
//2) mássalhangzót magánhangzó követ
//3) Speciális esetek pl. ssz-nél sz-sz elválasztás stb.
//A szótagokat -ekkel válaszd el
//
//4. Feladat
//Írj egy programot, ami eldönti egy szóról, hogy magas, mély vagy vegyes hangrendű
//
//5. Feladat
//Írj egy programot, ami bekér egy mondatot, illetve egy mondatbeli szót. A bekért mondatbeli szót tegye "" jelek közé és irassa ki úgy
//Legyen benne ellenőrzés, hogy ténylegesen előfordul-e a szó a mondatban, illetve, hogy ténylegesen egy szó és nem csak egy részlet.
//Írd meg úgy, is, hogy ha többször szerepel az adott szó a mondatban, akkor mindegyiket tegye ""-ek közé.