Wstawianie liczby do konkretnej linijki pliku

0

Cześć,
Mój algorytm ma za zadanie w przypadku zmieszczenia się w zakresie tablicy zapisać do niej liczbę a gdy wykroczy poza niego, wtedy ma zapisać daną wartość do pliku na konkretnej linii (tak żeby plik był swego rodzaju tablicą). W moim algorytmie który napisałem problem jest taki , że gdy zapiszemy przykładowo liczbę 10 do 10 linii to jest wszystko okej, ale jak już chcemy zapisać liczbę 9 do 9 linii to liczba 10 nagle przechodzi do linii pierwszej, gdy sie dopisze liczbę 8 do 8 linii wtedy liczba 9 spada na liczbę 10 do linii drugiej itd.. Ktoś widzi może jak to rozwiązać? Oto mój algorytm z funkcją main do testów:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
void save(int* tab, int i, int tabSize, int input) { 
    vector <string> copy;
    int Hmany = 0;                                            
    if (i < tabSize) {                                        
        tab[i] = input;
    }
    else {
        ifstream read;
        read.open("silnia1.txt");
        if (read.is_open()) {    
            int z = 0;

            for (z = 0; z<i - tabSize; z++) {
                string pass;
               // cout <<"i-tabSize:" <<i - tabSize << endl;
                read >> pass;
                copy.push_back(pass);
                Hmany++;
                pass.clear();
            }
            //cout<<"\n Hmany = "<<Hmany<<" \n ";

        }
        read.close();
        ofstream save;
        save.open("silnia1.txt");
        if (save.is_open()) {
            int z = 0;
            for (z = 0; z <= Hmany; z++) {
                if (z == i - tabSize) {
                    save << input << endl;
                }
                else {
                    string kopia = copy[z];
                    //cout << endl << copy[z] << " " << kopia << endl;
                    save << kopia << endl;
                }

            }

        }
        save.close();
    };

};
int main() {
	int n =1;
	int *tab;
	tab = new int[n];
	save(tab,10,n,10);
	save(tab,9,n,9);
	save(tab,8,n,8); 
	return 0;
}

0

Po pierwsze... Zamiast

if (read.is_open())

powinno być

if (!read.is_open())

i obsługa w przypadku nieotwarcia pliku. W swoim przypadku tracisz na czytelności kodu i narażasz się na taki błąd, jak zamykanie nieotwartego pliku (to w powyższym przykładzie zrobiłeś).

Po drugie... korzystaj z flag przy otwieraniu plików. Pozwala to uniknąć niespodziewanych zachowań programu:
http://www.cplusplus.com/reference/fstream/fstream/open/

Po trzecie... Twoja funkcja ma za dużo porozrzucanych zmiennych i dziwną logikę. Generalnie do poprawy.

0

Tej funkcji w sumie nie pisałem ja tylko mój znajomy i nic kompletnie tego nie rozumiem. Zacząłem teraz pisać funkcje sam i zacząłem od następującego kodu :

#include <iostream>
#include <fstream>
using namespace std;
void save(int where, int what){
	ofstream save;
	save.open("test.txt");
	if(save.is_open()){
		save.seekp(where);
		save<<what<<endl;
		save.close();
	}
	
}
int main() {
	save(0,5);
	save(1,2);
	save(2,3);
	return 0;
}

Jednak nie działa on tak jak chce bo zapisuje tylko tą liczbe z ostatniego wywołania funkcji a reszte usuwa, co robię nie tak?

0

Bez wgłębiania się na początku w sam przebieg funkcji, zacznij od mojej drugiej uwagi, czyli używaniu flag przy otwieraniu pliku.
Dla przykładu:

save.open("test.txt", ios::ate);

Przy otwarciu pliku ustawi wskaźnik na koniec pliku, a nie na jego początek, co chroni przed nadpisaniem poprzedniej zawartości.

0

No dobrze a jak bym chciał pracować tak na pliku by wstawiać w dowolnym miejscu dowolną liczbę? Musiał bym przed każdym zapisem kopiować całą zawartość pliku żeby chronić przed nadpisaniem czy istnieje inny sposób?

1

W pliku tekstowym nie ma czegoś takiego jak ,,dowolna linia".
Jeśli potrzebujesz wstawić np. 10 w 10 linii, wcześniej będziesz musiał uzupełnić poprzednie wiersze przynajmniej znakami nowej linii '\n'.
Kiedy ten warunek spełnisz, po pliku możesz się przemieszczać za pomocą

save.seekg(ios_base::cur, 5);

gdzie pierwszy argument oznacza punkt odniesienia, a drugi przemieszczenie. Więcej znajdziesz na:
http://www.cplusplus.com/reference/istream/istream/seekg/

Przemieszczając się umiejętnie po pliku nie będziesz nadpisywać danych. Otwierając plik z flagą unikasz czyszczenia danych.
Proponuje generalnie zgłębić wiedzę z obslugi plików z jakiejś książki lub kursu.

0

Na pewno poczytam jakąś książkę, póki co to napisałem kolejny program jednak coś nie działa z vectorem do którego chce kopiować zawartość pliku. Występuje błąd "vector subscript out of range i to już w pierwszej pętli for (według debuggera). Oto kod :

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;
int wielkosc = 0;
int wielkoscPliku(int wielkosc, int where) {
	if (where > wielkosc) {
		wielkosc = where;
	}
	return wielkosc;
}

void save(int where, int what) {
	int wielkoscc = wielkoscPliku(wielkosc, where);
	cout << wielkoscc << endl;
	vector <string> copy;
	ifstream odczyt;
	odczyt.open("test.txt");
	if (!odczyt.is_open()) {
		for (int z = 1; z <wielkoscc ; z++) {
			string zawartosc;
			odczyt.seekg(z, ios_base::beg);
			odczyt >> zawartosc;
			copy.push_back(zawartosc);
			zawartosc.clear(); // <------------- Tu wywala błąd
		}
	}
	copy[where] = what;
		ofstream save;
	save.open("test.txt", ios::ate);
	if (save.is_open()) {
		for (int z = 0; z <= wielkoscc; z++) {
			string kopia = copy[z];
			save.seekp(z, ios_base::beg);
			save << kopia << endl;
		}
		save.seekp(where);
		save << what << endl;
		save.close();
	}
}
int main() {
	save(2, 5);
	save(1, 2);
	save(2, 3);
	save(4, 2);
	return 0;
}


0

    copy[where] = what;

Jaką wartość ma where i jaki jest rozmiar copy w tym miejscu?

Nie mieszaj angileskiego z polskim w kodzie. Czyta się ciężko.

1 użytkowników online, w tym zalogowanych: 0, gości: 1