Scalenie dowolnej liczby plików w jednym nowym.

0

Witam. Mam problem z napisaniem programu w linuxie z bibliotekami linuxowymi który scala wiele plików tekstowych w jeden nowy. Ciągle program mi staje na tworzeniu pliku nowego i zwraca błąd i nie może utworzyć pliku. Piszę to wszystko na ubuntu.

#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <vector>
#include <fstream>
#include <cstdlib>
#include <iostream>
#define MAX 512
using namespace std;
int main(int argc, char* argv[])
{
    char buf[MAX];
    int desc_cel;
    int lbajt;
    vector <int>zrodlo;
    if (argc < 3)
    {
        fprintf(stderr, "Za malo argumentow. Uzyj:\n");
        fprintf(stderr, "%s <plik zrodlowy> <plik zrodlowy> ... <plik docelowy>\n", argv[0]);
        exit(1);
    }

for(int i=1; i<=argc-2; i++)
{
    zrodlo.push_back(open(argv[i], O_RDONLY));
    if (zrodlo[i] == -1)
    {
        perror("Blad otwarcia jednego z plików zrodlowych, sprawdz poprawnosc plikow");
        exit(1);
    }
}
  
    int n = zrodlo.size();

    cout<<"zrodlo.size = "<<n<<endl;
    desc_cel = creat(argv[n+1], 0640);
    if (desc_cel == -1)
    {
        perror("Blad utworzenia pliku docelowego");
        exit(1);
    }

          
for(int h=0; h<=n; h++)
{
    while ((lbajt = read(zrodlo[h], buf, MAX)) > 0)
    {
        if (write(desc_cel, buf, lbajt) == -1)
        {
            perror("Blad zapisu pliku docelowego");
           exit(1);
      }
    }
}

    if (lbajt == -1)
    {
        perror("Blad odczytu pliku zrodlowego");
        exit(1);
    }
for(int o=0; o<n; o++)
{
    if (close(zrodlo[n]) == -1)
    {
        perror("Blad zamkniecia pliku");
        exit(1);
    }
}
    if (close(desc_cel) == -1)
    {
        perror("Blad zamkniecia pliku");
        exit(1);
    }

    exit(0);
}
1

Sprawdź errno to będziesz wiedział jaka jest przyczyna błędu. Dla creat jest tych możliwości trochę. Posix ma też funkcję, która konwertuje errno na string, strerror chyba się nazywała, ale nie dam głowy, na pewno jest jakaś.

0

Dobra jestem na etapie, gdzie program po stworzeniu pliku ciągle wrzuca w nieskończoność pierwszy plik zamiast przejść do następnego.

desc_cel = creat(argv[n+1], 0640);
    if (desc_cel == -1)
    {
        perror("Blad utworzenia pliku docelowego");
        exit(1);
    }    
for(int h=0; h<=n; h++)
{
    while ((lbajt = read(zrodlo[h], buf, MAX)) > 0)
    {
        if (write(desc_cel, buf, lbajt) == -1)
        {
            perror("Blad zapisu pliku docelowego");
           exit(1);
      }
    }
}
    if (lbajt == -1)
    {
        perror("Blad odczytu pliku zrodlowego");
        exit(1);
    }
for(int o=0; o<n; o++)
{
    if (close(zrodlo[n]) == -1)
    {
        perror("Blad zamkniecia pliku");
        exit(1);
    }
}
    if (close(desc_cel) == -1)
    {
        perror("Blad zamkniecia pliku");
        exit(1);
    }

    exit(0);
}
0

Zamień

for(int i=1; i<=argc-2; i++)

na

for(int i=1; i<argc; i++)

oraz

for(int h=0; h<=n; h++)

na

for(int h=0; h<n; h++)

i sprawdź co się stanie.

0

Wyskakuje błąd "Bad adress" przy próbie utworzenia pliku docelowego

0

A, spoko, bo docelowy masz chcesz mieć na końcu argv, tak więc na początku powinieneś mieć taką pętle

for(int i=1; i<argc-1; i++)
0

No i wszystko działa do momentu pętli for która zapisuje w nowym pliku tzn się w nieskończoność dopisuje pierwszy plik wpisany do polecenia. Po przepisaniu pliku program nie wychodzi z pętli while i ciągle działa w kółko, mimo, że gdy napisałem wersję dla scalenia tylko dwóch plików w jeden nowy to działał ten program.

for(int h=0; h<n; h++)
{
    while ((lbajt = read(zrodlo[h], buf, MAX)) > 0)
    {
        if (write(desc_cel, buf, lbajt) == -1)
        {
            perror("Blad zapisu pliku docelowego");
           exit(1);
      }
    }
}

Wersja dla dwóch plików, tutaj nie było co owijać w wektor, po prostu dwie te same funkcje dla różnych zmiennych zródłowych.

while ((lbajt = read(desc_zrod, buf, MAX)) > 0)
    {
        if (write(desc_cel, buf, lbajt) == -1)
        {
            perror("Blad zapisu pliku docelowego");
            exit(1);
        }
    }
        while ((lbajt = read(desc_zrod2, buf, MAX)) > 0)
    {
        if (write(desc_cel, buf, lbajt) == -1)
        {
            perror("Blad zapisu pliku docelowego");
            exit(1);
        }
    }
2

No to szczerze pisząc nie wiem dlaczego Ci nie działa, właśnie sprawdziłem poniższy kod i merdzuje dwa krótkie, ale tez nie trywialne, pliki bez problemu. Musiałem tylko małego fixa zrobić w pętli zamykającej i program zamknął się bez błędów.

merging.gif

#include <stdio.h>
#include <vector>
#include <fstream>
#include <cstdlib>
#include <iostream>
#define MAX 512
using namespace std;
int main(int argc, char *argv[]) {
  char buf[MAX];
  int desc_cel;
  int lbajt;
  vector<int> zrodlo;
  if (argc < 3) {
    fprintf(stderr, "Za malo argumentow. Uzyj:\n");
    fprintf(stderr, "%s <plik zrodlowy> <plik zrodlowy> ... <plik docelowy>\n",
            argv[0]);
    exit(1);
  }

  for (int i = 1; i < argc - 1; i++) {
    zrodlo.push_back(open(argv[i], O_RDONLY));
    if (zrodlo[i] == -1) {
      perror("Blad otwarcia jednego z plików zrodlowych, sprawdz poprawnosc "
             "plikow");
      exit(1);
    }
  }

  int n = zrodlo.size();

  cout << "zrodlo.size = " << n << endl;
  desc_cel = creat(argv[n + 1], 0640);
  if (desc_cel == -1) {
    perror("Blad utworzenia pliku docelowego");
    exit(1);
  }

  for (int h = 0; h < n; h++) {
    while ((lbajt = read(zrodlo[h], buf, MAX)) > 0) {
      if (write(desc_cel, buf, lbajt) == -1) {
        perror("Blad zapisu pliku docelowego");
        exit(1);
      }
    }
  }

  if (lbajt == -1) {
    perror("Blad odczytu pliku zrodlowego");
    exit(1);
  }
  for (int o = 0; o < n; o++) {
    if (close(zrodlo[o]) == -1) {
      perror("Blad zamkniecia pliku");
      exit(1);
    }
  }
  if (close(desc_cel) == -1) {
    perror("Blad zamkniecia pliku");
    exit(1);
  }

  exit(0);
}

0

Działa w końcu! Nie wiem co się działo, że się psuł program. Dzięki za pomoc :)

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