Miten voi kirjoittaa tiedostoon ja valita rivin johon kirjoittaa?
Niin ja tietty lukeminen tietystä kohdasta?
Esim. on tälläinen tekstipätkä
654
456
654
12
909
Niin miten voisi lukea tuosta tekstitiedostosta neljännen rivin ja laittaa sen luku muuttujaan rivi4?
Tiettyyn kohtaan ei voi kirjoittaa, tiedosto pitää kirjoittaa kokonaan uudestaan alusta loppuun asti, tai kirjoittaa vain sen loppuun.
Sen sijaan että yrittäisit tallentaa tiettyyn riviin jotain, tallenna jokainen rivi yhtä pitkäksi, jolloin sinun täytyy vain laskea yhdellä kertolaskulla se kohta josta luet sen rivin, tai se kohta johon tallennat.
Tallentaminen menee yleensä niin, että tallennettaisiin rivejä normaalisti niin kauan kunnes kyseessä on se rivi jota haluat muokata, kun tämä haluamasi rivi on meneillään, tunget siihen sen datan jolla haluat korvata vanhan rivin.
Eli siis jotenkin näin:
#include <stdio.h>
int main (void) {
char buffer[50];
int i=1;
int rivi=4;
char korvaus[] = "Hello World";
FILE filu; //luetaan
FILE mihi; //kirjotetaan
filu = fopen("file.txt", "r");
mihi = fopen("kirjotus.txt", "w");
while(!EOF(filu)) {
fscanf(filu, "%s", &buffer);
if(i==rivi) fprintf(mihi, "%s\n", korvaus);
else fprintf(mihi, "%s\n", buffer);
//jos rivi on se korvattava, kirjoitetaan korvausteksti
i++;
memset(&buffer, 0, 50);
}
fclose(mihi);
fclose(filu);
}Huom,kirjoitettu ilman manuskaa kännykällä, joten korjaa pilkkuvirheet. Idea on silti tuo.
Onkohan kieli C, C++ vai Pascal? Meinaan että tällöin osattaisiin neuvoa hieman paremmin.
Korjataanpa tuosta Laakkosen esimerkistä ne pari virhettä: EOF => feof ja kahdesti &buffer => buffer. Lisäksi pitäisi muistaa kaksi asiaa: %s aiheuttaa tuossa ylivuodon, jos tiedostossa on 50 merkin mittaisia sanoja, ja lisäksi se lukee vain yhden sanan eikä riviä. Jostain pitää siis selvittää, onko jo rivinvaihto kohdalla, ja välit jäävät kopioimatta.
Pitkä, joo, mutta pitäisi toimia ainakin:
int kopioi_rivi(FILE *lahde, FILE *kohde)
{
int i;
// "Ikuinen" silmukka lukee merkkejä
while (1) switch ((i = fgetc(lahde))) {
case EOF:
// EOF on tiedoston loppuminen, palautetaan -1
return -1;
default:
// Muuten kirjoitetaan merkki kohdevirtaan, jos sellainen on
if (kohde && fputc(i, kohde)) {
return -2; // Virhe, palautetaan -2
}
// Jos se oli rivinvaihto, lopetetaan
if (i == '\n') {
return 0;
}
}
}
//...
int korvattava_rivi = 10;
char korvaava_rivi[] = "Koodarin 10. eli tavallisen ihmisen 11. rivi. :)";
int i, j;
// Ensin alkupuoli tiedostosta
for (i = 0; i < korvattava_rivi; ++i) {
if ((j = kopioi_rivi(lahde, kohde))) {
printf("Virhe %d!\n", j);
exit(-1);
}
}
// Sitten se korvattava rivi, ja tietenkin poistettava pitää kopioida ei-minnekään
if (fprintf(kohde, "%s\n", korvaava_rivi) != 1) {
printf("Virhe!\n");
exit(-1);
}
kopioi_rivi(lahde, 0);
// Kopioidaan vielä loputkin tiedostosta
while ((j = kopioi_rivi(lahde, kohde) == 0));
// Mihin loppui?
switch (j) {
case -1:
printf("Tiedosto loppui. :o\n");
break;
case -2:
printf("Kirjoitus epäonnistui!\n");
}Laitoin tuon 50 merkkiä tuohon puskuriksi sen kummempia säätämättä, koska Jartsalan tiedostossa näyttää olevan vain kolmimerkkisiä rivejä. Toki Metabolixin tapa on huomattavasti hienompi, mutta Jartsalan taitojen taso vain huolestuttaa. Toisaalta, on varmasti parempi opetella heti alkuun hyvin.
Aihe on jo aika vanha, joten et voi enää vastata siihen.