Zapisywanie z potoku do tablicy charów

0

Mam następujący problem: Chcę zczytać sobie potok do tablicy charów, żeby potem odszukać w niej nazwy katalogów pokazanych przez ls. Znalazłem przykładowy kod, lekko zmodyfikowałem (oznaczone komentarzem linie) i lipa - nie działa. Niby się kompiluje, ale jak odpalam, to pisze: "Segmentation fault". Wie ktoś dlaczego?

 #include <stdio.h>
  
  int main(void)
  {
          FILE *pipein_fp, *pipeout_fp;
          char readbuf[80];
  
          /* Tworzymy jednokierunkowy potok za pomocą popen() */
          if (( pipein_fp = popen("ls", "r")) == NULL)
          {
                  perror("popen");
                  exit(1);
          }
  
          /* Tworzymy jednokierunkowy potok za pomocą popen() */
          if (( pipeout_fp = popen("sort", "w")) == NULL)
          {
                  perror("popen");
                  exit(1);
          }
//		char *tablica;
//		int i=0;
          /* Przetwarzanie */
          while(fgets(readbuf, 80, pipein_fp)){
/*	tablica[i]= */ fputs(readbuf, pipeout_fp);
//	  	i++;
  		}
  
          /* Zamknięcie potoków */
          pclose(pipein_fp);
          pclose(pipeout_fp);
  
          return(0);
  }
  
0

u mnie naruszenia ochrony pamięci nie ma,
ale jak chcesz odczytać tylko nazwy katalogów z bieżącego katalogu to nie łatwiej od razu zrobić to potokiem?

#include
#define dlugosc_linii 40

int main(void) {
 FILE * potok, * potok_dla_sorta;
 char bufor[dlugosc_linii];
 if ((potok = popen("find -type d", "r")) == NULL) exit(1);
// mozesz tez napisac 
// if ((potok = popen("find ~/ -type d", "r")) == NULL) exit(1);
// wtedy wyszuka wszystkie katalogi z katalogu uzytkownika

 if ((potok_dla_sorta = popen("sort", "w")) == NULL) exit(1);

 while (fgets(bufor, dlugosc_linii, potok))
  fputs(bufor, potok_dla_sorta);
// wypisze na ekranie posortowane katalogi

 pclose(potok);
 pclose(potok_dla_sorta);
 return 0;
}

0

Aha, okej, ale w zasadzie to samo robi program, który poprzednio wkleiłem... Moim głównym celem jest nie wyświetlenie tej posortowanej listy katalogów, ale zapisanie w tablicy ciągu znaków, który jest wyświetlany... Tablica będzie duża, fakt, ale nie mam wyjścia, bo muszę na niej parę operacji wykonać (poszukać takich rzeczy, jak nazwa, czas utworzenia, właściciel... Trochę poprawiłem mój poprzedni kod:
Już jest lepiej. Wiem, co bylo mniej wiecej nie tak w poprzednim kodzie, ale nadal mam ogromny problem...: Wyswietla sie nazwa jednego katalogu :), ale reszta to śmiecie...Czemu?

 #include <stdio.h>
  
  int main(void)
  {
          FILE *pipein_fp, *pipeout_fp;
          char readbuf[800];
  
          /* Tworzymy jednokierunkowy potok za pomocą popen() */
          if (( pipein_fp = popen("ls", "r")) == NULL)
          {
 //         	  perror("popen");
  //	     	  exit(1);
          }
  
          /* Tworzymy jednokierunkowy potok za pomocą popen() */
      if (( pipeout_fp = popen("sort", "w")) == NULL)
    {
         //         perror("popen");
         //         exit(1);
     }
  	
          /* Przetwarzanie */
          while(fgets(readbuf, 800, pipein_fp)){
		fputs(readbuf, pipeout_fp);

  		}
  
          /* Zamknięcie potoków */
          pclose(pipein_fp);
          pclose(pipeout_fp);
	  int j;
	  for(j=0;j<800;j++)
 		printf("%c", readbuf[j]);
          return(0);
  }

Wyświetla co prawda jeden katalog (hura, został on zapisany do tablicy!), ale tylko jeden, a potem jakieś śmiecie... Dlaczego? Ma ktoś pojęcie, co jest nie tak?

0

czyli w sumie program ma skopiować polecenie "ls -l" do tablicy?

no to tak... polecenie fgets(readbuf, 800, pipein_fp) odczyta ze strumienia do zmiennej readbuf tylko jedną linię zakończoną znakiem nowej linii, to co bedzie za znakiem nowej linii zostanie jako nieuzywane. Prawdopodobnie wypisuje Ci tylko ostatni z plików w bieżącym katalogu bo to jest ostatnia linia jaką odczytał. Wypisując zawartość tablicy pętlą for(j=0; j<800; j++) printf("%c", readbuf[j]);wypisujesz każdy znak z ostatniej odczytanej linii. Pewnie wyświetla Ci się ostatni plik, przejscie do nowej linii, i ciąg krzaków.
Reasumując powinieneś stworzyc tablicę dwuwymiarową w której bedziesz przechowywał poszczególne linijki. Możesz zrobić to statycznie albo dynamicznie. Niestety z tego co sie orientuje C nie pozwala zmieniać rozmiaru tablic dwuwymiarowych dynamicznie (chodzi o dodanie wiersza funkcją realloc) więc bez pisania nowych funkcji mozesz to zrobić jedynie statycznie.
Nie wiem czy dokładnie o to Ci chodziło ale poniżej wklejam kod który kopiuje wszystko z ls -l do tablicy i wypisuje na ekran. Może Ci to pomoże.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define dlugosc_linii 100
#define max_wierszy 100

int main(void) {
	FILE * potok;
	char bufor[dlugosc_linii];
	if ((potok = popen("ls -l", "r")) == NULL) exit(1);
	char ** tablica = calloc(max_wierszy, sizeof(char*));
	int i=0;
	while (fgets(bufor, dlugosc_linii, potok) && i<max_wierszy) {
		tablica[i] = calloc(strlen(bufor), sizeof(char));
		strncpy(tablica[i], bufor, strlen(bufor)-1);
		i++;
	}
	pclose(potok);
	potok=NULL;
	for (int j=0; j<i; j++) {
		printf("%s\n", tablica[j]);
	}
	for (int j=0; j<max_wierszy; j++) free(tablica[j]);
	free(tablica);
	tablica=NULL;
	return 0;
} 
</url>
0

Super! Dzięki kolego. Chyba chodziło mi o to :P, a jest nawet lepiej, bo z 2-wymiarowej tablicy sobie elegancko wszystko odczytam. Btw, nie kompiluje się twój kod (według standardu C99 - ja mam gcc na Ubuntu, który to obsługuje, nie można zrobić deklaracji j wewnątrz fora), ale po poprawce jest ok.

Pozdrawiam!

0

na Arch'u przy gcc -Wall -std=c99 przechodzi ;-) bez standardu owszem, trzeba int j wyrzucić przed for'a

pozdr!

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