Hogy lehet C-ben egy fájlnak a sorát módosítani?
Pl. van egy szöveges fájl teszt.txt és van benne 5 sor
sor1
sor2
sor3
sor4
sor5
és a sor3-at átszeretném írni másra.
Ezt, hogy lehetne megvalósítani?
Eddig eljutottam:
char line[128]="";
FILE * fp = fopen("teszt.txt", "a+");
while(!feof(fp)){
fscanf(fp, "%s", line);
if(!strcmp(line, "sor3")){
//és lényegében itt nem tudom, hogy most fputs vagy fwriteot kellene használnom és, hogy hogyan használjam, hogy a sor elejéről induljon a szöveg ne a szöveg után
break;
}
}
fclose(fp);
// Az "a+" megnyitási móddal csak a fájl végére lehet írni.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define LINE_SIZE 1024
int main(int argc, char *argv[])
{
const char * file_name = "teszt.txt";
char * temp_file_name = "s4oxw61r.tmp";
char line[LINE_SIZE] = "";
FILE * fp;
FILE * tmpf; // temp file
int isSuccess = 0;
tmpf = fopen(temp_file_name, "w");
if (tmpf != NULL) {
fp = fopen(file_name, "r");
if (fp != NULL) {
while (fgets(line, LINE_SIZE, fp) != NULL) {
if (!strcmp(line, "sor3\n")) {
fprintf(tmpf, "%s\n", "Hello, world!");
} else {
fprintf(tmpf, "%s", line);
}
}
isSuccess = 1;
fclose(fp);
}
fclose(tmpf);
}
if (isSuccess) {
remove(file_name);
rename(temp_file_name, file_name);
}
return EXIT_SUCCESS;
}
Köszönöm a válaszokat!
Még annyit megszeretnék kérdezni, hogy ha megnyitom a fájlt elkezdem megkeresni a keresendő sort az fgets-el és ha megvan leállítom a while ciklust break-el majd fseek-el vissza megyek a sor elejére úgy, hogy ftell(fp)-strlen(line) majd oda fwrite-al beírok mást akkor a következő sor miért látja kárát?
FILE * fp = fopen("teszt.txt", "r+");
while(fgets(line, 128, fp)){
if(!strcmp(line, "sor3")){
fseek(fp, ftell(fp)-strlen(line), SEEK_SET);
fwrite("teszt\n", 1, 6, fp);
break;
}
}
fclose(fp);
A "teszt\n" amit szeretnék helyettesíteni a sor3-al sikerül is csak a következő sor a sor4-ből annyi marad, hogy or4 ahány karakterrel hosszabb a behelyettesített sor annyival lesz rövidebb a következő sor eleje.
Ezzel lehet kezdeni valamit?
És most végül a 2D tömbbe való beolvasás szerkesztés majd visszaírás a fájlba módszer a jobb vagy a fájlból kiolvasás nyitni egy másik fájlt szerkeszteni az adott szöveget majd visszaírás az új fájlba jobb?
Egy kb. 1000 soros szöveges fájlnál melyik lehet a legjobb megoldás?
Neked jelen esetben a 2d módszer a jobb.
Am it én fölöslegesnek tartok, az a 3. sor komparálása beépített stringgel. Ez számomra fölösleges is meg nevetséges is egy kicsit.
Abszolút nem életszerű.
Az lenne jó szerintem, ha a sorvég jelek alapján tudnád meghatározni, hogy a 3. sorhoz érkeztél, amit egy változóba áttéve, azt átírva kiírnád a file-ba. A TMP file is fölösleges, ha rendesen van megírva nyitás, zárás és ha korrektül lockolod a file-t. Utóbbi csak linux alatt kell, win alatt ez automatikus.
"...a következő sor miért látja kárát? "
Mivel a fájl tartalma úgy épül fel, hogy egy sor szöveg sorvégjel, egy sor szöveg, sorvégjel stb. Ha egy sort csak úgy simán átírsz a fájlba direktbe, hogy csak oda seek-elsz és átírod, akkor alapjában véve 3 eset lehet:
1.) Az új szöveg helyigénye több mint ami volt ott akkor felülírod a szöveggel együtt az utána következő sorvégjelet is. A következő sorba is belerondíthatsz vagy több sorba is akár. Sőt a fálj struktúrális feléptésébe is belerondíthatsz ezzel, ha például windowsos formátumó fáljba írsz ahol az új sor két vezérlőkarakrből áll, melyek a carriage return (kocsi vissza) és a line feed (soremel). Ebből ha az egyiket felülírod a másik marad, akkor sérült a fáj struktúrális felépítése.
2.) Kevesebb szöveged írsz be mint ami volt a sorba, akkor az új szöveg után lesz a régiből is annyi amennyivel többet foglal a régi nála.
3.) Pont a régi és az új szöveg is egyforma hosszú bájszámba mérve, ebben az egy esetben írja át megfelelően azt az egy sort.
Éppen ezért formálisan az adott sor és amire módosítani akarjuk ezek bájthosszúsága közötti előjelesen értelmezett különbség függvényében kellene pontosan arrébb másolni minden utána következő bájtot a fájlon belül az újonnan módosított sor végére rákövetekző bájtpozíciótól. Erre a standard megoldás memóriába 2D-s tömbökkel. Többek között azért mert előre nem ismert mennyiségő sor módosítás lehetésges és elég lassú lenne mindig tologatni a fájlban. Vagyis a memóriában szerkeszeni, majd a memóriából újraépíteni a fájlt.
(Zárójeles megjegyzés:
Amit kihagytam a múltkorihoz, ami ahhoz kapcsolódik, hogy a plain text editor 2D-s tömböt használ. Egy 2D-s tömb memória reprezentánsa az nem is csak egy módon lehetséges, ez az egyik. Csak azért ha valaki nézegetné, akkor ezt vegye figyelembe. A másik hogy nem zárom ki, hogy ne lenne olyan szerkesztő amely másfajta adatszerkezetbe dolgozza fel, olyan hogy nem is biztos hogy beránja az egészet a memóriába,stb, de ez a tömbös a memóriában az egész egy lényegesen jellemző megvalósítás.)
Régen, nem nyúltam már ansi c-hez, ideje volt feleleveníteni.
A kód az a main függvénybe van ami szemlélteti is egyben amit a kérdező írt. Ami ezen kívül van mint saját kód az keretrendszer része hozzá, ezt külön fájlba szokták írni amit beinclude-olnak, én egybe raktam, mivel utólag szoktam volt külön fájlokba szedni, illetve közbe is amikor már szét van, amíg úgy ítélem meg hogy szükséges. Itt meg jónak tartom most, hogy így legyen a kérdező szempontjából.
Ellenőrzöm, hogy windows-os formátumú volt e, a szerint írom vissza. Az inputFilename és a az outputFilename, az eszembe se jutott volna ha valaki nem említi meg hogy veszélyes ugyanoda visszarakni. Itt működik, ha ugyanaz ha nem.
Egy List-be tárolom a sorokat, ami egy c-s 2D-s tömb kiokosított változtaban. A createList() hoz létre dinamikusan egy List-et, a setListElemet(list,3 -1,"Hello world!"); azért 3 -1 azaz 2, mert az indexelés 0-tól indul, és a 2-es index jelöli a 3.-ik sort.
A kód magáért beszél : link : pastebin pont com per SdL6Xydv , a pontot meg a pert cseréld ki értelem szerűen, máshogy nem engedte.
Például így lehet felépíteni a memóriába egy szövegfájlból egy dinamikus adatszerkezetet.
Egy apró javítás az előzőhöz: pastebin pont com per QrCazKeq
Nem sokkal ahogy elküldtem utána beugrott ez valahogy, de nem volt időm már vele foglalkozni.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!