LINUX.ORG.RU

scandir


0

1

помогите написать код со scandir чтобы он выводил из заданной директории только те папки , имена которых состоят из цифр


Ответ на: комментарий от suv121
char* dirname[100];
int size;

void openfile(const char* name)
{
  char* filename;
  filename = (char*)malloc(256);
  sprintf(name,"/proc%s/status",dirname);
  int fil =
   open(fil,O_RDWR);
  //далее считываешь сравниваешь и т.д. читай гугл
}

........................       
if (n < 0)
               perror("scandir");
           else {
               size = n;//запомнить размер
               while (n--) {
                   //printf("%s\n", namelist[n]->d_name);
                   if(isDigit(namelist[n]->d_name))
                   {
                       dirname[n]=namelist[n]->d_name; //можешь тупо так.. без динамики
                   } 
                   //free(namelist[n]);
               }
.............................

while(size--)
{
   openfile(dirname[size]);
}
pozitiffcat ★★★
()
Ответ на: комментарий от Eddy_Em

Типичный человек имея представления о си будет писать на крестах как си с классами, порождая тонны говнокода.

tensai_cirno ★★★★★
()
Ответ на: комментарий от Eddy_Em

>Если начинать учить плюсы, не имея вообще никакого представления о сях, ничего хорошего не выйдет.

это ещё почему? C и C++ - абсолютно разные языки, а то что первый частично является подмножеством второго - всего лишь историческое недоразумение(хитрый план, ага).

lazyklimm ★★★★★
()
Ответ на: комментарий от Eddy_Em

>&isNum будет уже двойным указателем :)

Если f — фfункция, то значения и типы выражений f и &f одинаковы.

Yareg ★★★
()

Берите:

#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include<dirent.h>
int isNum(const struct dirent *de){ 
  char *s = strdup(de->d_name), *ptr;
  ptr = s;
  int r;
  while (isdigit(*ptr)) ptr++; 
  r = !*ptr;
  free(s);
  return r; 
}

int main(){
FILE* f;
char buf[60];
       char* p=buf;
       int pid,n,i,c;
       char **names;
char way[60]="/proc";
struct dirent **namelist;
n = scandir(way, &namelist, isNum, alphasort);
if (n < 0){
perror("scandir");
          }
else {
names=(char**)malloc(n*sizeof(char*));
for(i=0;i<n;i++){
names[i] = strdup(namelist[i]->d_name);
                }
for(i=0;i<n;i++){
printf("f[%d]=%s\n", i, names[i]);
                }
                }
}
Оптимизировать лень (*ptr++ = strdup((*d_ptr++)->d_name);), мусор чистить - сами думайте как (сегодня тяпница).

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Да, могли бы сразу сказать, что надо по /proc искать чего-то.

В догонку, может поможет:

#define PROC_BASE "/proc"
void readname(char *name, pid_t pid){ // считать имя процесса из /proc/...
	char *pp = name, byte, path[256];
	int cntr = 0, file;
	sprintf (path, PROC_BASE "/%d/cmdline", pid);
	file = open(path, O_RDONLY);
	do{	// считываем имя без слешей
		read(file, &byte, 1);
		if (byte != '/') *pp++ = byte;
		else pp = name;
	}
	while(byte != EOF && byte != 0 && cntr++ < 255);
	close(file);
}
void killbrothers(int flag){
	DIR *dir;
	struct dirent *de;
	pid_t pid, self;
	char name[256], myname[256];
	if (!(dir = opendir (PROC_BASE))){ // открываем директорию /proc
		perror (PROC_BASE);
		exit (1);
	}
	self = getpid(); // свой идентификатор
	readname(myname, self); // свое имя процесса
	while ((de = readdir (dir)) != NULL){ // пока не дойдем до конца директории
	// пропустим, если директория не указывает на процесс, или указывает на self
		if (!(pid = (pid_t) atoi (de->d_name)) || pid == self)
			continue;
		readname(name, pid); // считываем имя процесса
		if(strncmp(name, myname, 255) == 0){ // если оно совпадает с self
			WARN("\nFound running process (pid=%d), ", pid);
			if(flag){
				WARN("killing\n");
				kill(pid, SIGQUIT); // убиваем, если flag != 0
			}
			else{
				WARN("exiting.\n");
				kill(pid, SIGUSR1);
				exit(0);
			}
		}
	}
	closedir(dir);
}

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от pozitiffcat
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include<dirent.h>
char isNum(const char* name)
{
  int i=strlen(name)-1;
  do{ if (!isdigit(name[i])) return 0; } while(i--);

   return 1;
}

int openfile(const char* name,const char* name2)
                              {
                              char* filename;
                              int i,x;
                              filename=(char*)malloc(256);
                             sprintf(name,"/proc/%s/status", dirname);
                              FILE* f=fopen(f,"r");
                             for(x=0;fgetc(f)=='\n';x++){
                                                     filename[x]=fgetc(f);
                                                         }
                              if(strcmp(name2,filename)==0){
                                      for(x=0;x<60;x++){
                                      printf("%s",name2[x]);
                                                        }
                                      for(x=0;x<60;x++){
                                      pritf("%s",name[x]);
                                                                        }
                              fclose(f);
                             return 0;
                             }                            }

main(){
      FILE* f;
      char* dirname[100];
      int pid,n,i,c;
      char name_p[60];
      char way[60]="/proc";
      printf("enter 'Name: name_procces': ");
      fgets(name_p,sizeof name_p,stdin);
      if(name_p[strlen(name_p)-1]=='\n'){
                                        name_p[strlen(name_p)-1]='\0';
                                        }
      printf("\n");

      struct dirent **namelist, **d_ptr;
      n = scandir(way, &namelist, 0, alphasort);
      if (n < 0){
      perror("scandir");
                }
      else {
           c=n;
           while(n--){
               if(isNum(namelist[n]->d_name)){
                                             dirname[n]=namelist[n]->d_name;
                                             }
              free(namelist);
                     }
           while(size--){
                        openfile(dirname[size],name_p[60]);
                        }
      pid=getpid();
      printf("\nPid this programm:%d\n",pid);
      for(n=0;;n++){
      printf("\nPid this programm:%d\n",pid);
      for(n=0;;n++){
                   printf("enter kill pid:");
                   scanf("%d",&i);
                   kill(i,SIGKILL);
                   printf("\n If that all press 1\n If that not all press 2 \n");
                   scanf("%d",&i);
                   if(i==1){break;}
                   else continue;
                   }
}

suv121
() автор топика
Ответ на: комментарий от suv121

пипец намудрил

int openfile(const char* name,const char* name2)
                              {
                              char* filename;
                              int i,x;
                              filename=(char*)malloc(256);
                             sprintf(filename,"/proc/%s/status", name);//тут поправил
                              FILE* f=fopen(filename,"r");//тут поправил
//дальше забил проверять.. проверяй сам и включи мозг
                             for(x=0;fgetc(f)=='\n';x++){
                                                     filename[x]=fgetc(f);
                                                         }
                              if(strcmp(name2,filename)==0){
                                      for(x=0;x<60;x++){
                                      printf("%s",name2[x]);
                                                        }
                                      for(x=0;x<60;x++){
                                      pritf("%s",name[x]);
                                                                        }
                              fclose(f);
                             return 0;
                             }   

pozitiffcat ★★★
()
Ответ на: комментарий от suv121

const char* name
sprintf(name,«/proc/%s/status», dirname);
ЗЫ: никогда не пытайся писать в константы

pozitiffcat ★★★
()
Ответ на: комментарий от suv121
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include<dirent.h>
char isNum(const char* name)
{
  int i=strlen(name)-1;
  do{ if (!isdigit(name[i])) return 0; } while(i--);

   return 1;
}

char* getLine(FILE* f(
{
   char ch = getc(f);
   char* str=(char*)malloc(256);
   int cnt = 0;
   while(ch!='\n')
   {
      str[cnt]=ch;		
      ch = getc(f);
      cnt++;
   }
   return str;
}

int openfile(const char* name,const char* name2)
                              {
                              
                              char* filename;
                              int i,x;
                              filename=(char*)malloc(256);
                             sprintf(filename,"/proc/%s/status", name);
                              FILE* f=fopen(f,"r");
                              char* mystr = getLine(f);
                              if(strncmp(name2,mystr)>0) print("%s  -  %s",filename,name2);
                             return 0;
                             }                            

main(){
      char* dirname[100];
      char* str = "Заданная строка";
      struct dirent **namelist;
      n = scandir(way, &namelist, 0, alphasort);
      if (n < 0){
      perror("scandir");
                }
      else {
           size=n;
           while(n--){
               if(isNum(namelist[n]->d_name)){
                                             dirname[n]=namelist[n]->d_name;
                                             }            
                     }
           while(size--){
                        if(dirname[size]) openfile(dirname[size],str);
                        }
      
                   }
}

как-то так

pozitiffcat ★★★
()
Ответ на: комментарий от pozitiffcat
 #include<stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <signal.h>
 #include<dirent.h>

char isNum(const char* name) { 
int i=strlen(name)-1; 
do{ 
if (!isdigit(name[i])) return 0; 
} 
while(i--);

return 1; 
}

int openfile( char* name, char* name2){
 char* filename;
 int i,x; 
filename=(char*)malloc(256);
 sprintf(filename,"/proc/%s/status", name); 
FILE* f=fopen(filename,"r");
 for(x=0;fgetc(f)=='\n';x++){
 filename[x]=fgetc(f);
 } 
if(strcmp(name2,filename)==0){
 for(x=0;x<60;x++){
 printf("%s",name2[x]);
 }
 for(x=0;x<60;x++){
 printf("%s",name[x]);
 } 
}
 fclose(f);
 return 0; } 

main(){ 
char* dirname[100];
 int pid,n,i,c;
 char name_p[60];
 char way[60]="/proc"; 
printf("enter 'Name: name_procces': ");
 fgets(name_p,sizeof name_p,stdin); if(name_p[strlen(name_p)-1]=='\n'){
 name_p[strlen(name_p)-1]='\0';
 }
 printf("\n");

struct dirent **namelist, **d_ptr;
 n = scandir(way, &namelist, 0, alphasort);
 if (n < 0){
 perror("scandir"); 
}
 else { c=n; while(n--){ 
if(isNum(namelist[n]->d_name)){
 dirname[n]=namelist[n]->d_name;
 }
 free(namelist);
 } 
while(c--){ openfile(dirname[c],name_p[60]); 
}
 pid=getpid();
 printf("\nPid this programm:%d\n",pid);
 for(n=0;;n++){
 printf("enter kill pid:"); 
scanf("%d",&i);
 kill(i,SIGKILL);
 printf("\n If that all press 1\n If that not all press 2 \n"); scanf("%d",&i);
 if(i==1){break;
}
 else continue; 
}

}
 } 

подредактировал , компилируется, но выдает ошибку при выполнении

suv121
() автор топика
Ответ на: комментарий от suv121

вродебы все хорошо, но в отладчике scandir возвращает какуюто лажу в названиях директорий


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>


bool isNum(const char* name)
{
   bool exists;
   char* nums = "0123456789";
   for(int i=0;i<sizeof(name);i++)
   {
     exists = false;
     for(int j=0;j<10;j++)
     {
        if (name[i]==nums[j])
        {
              exists = true;
              break;
        }
     }
      if(!exists) return false; //сто пудова не число
   }
   return true; //число
 }

char* getLine(FILE* f)
{
    if(f!=NULL)
    {
       char* ch = (char*)malloc(1);
       fread(ch,1,1,f);
       char* str=(char*)malloc(256);
       int cnt = 0;
       while(ch[0]!='\n')
       {
          str[cnt]=ch[0];
          fread(ch,1,1,f);
          cnt++;
       }
       return str;
    }
}

int openfile(const char* name,const char* name2)
                              {

                              char* filename;
                              int i,x;
                              filename=(char*)malloc(256);
                              for(int i=0;i<256;i++)
                                  filename[i]=0;
                             sprintf(filename,"/proc/%s/status", name);
                              int exists = open(filename,O_RDWR);
                              if(i<=0) return 0;
                              close(exists);
                              FILE* f=fopen(filename,"r");
                              if(f!=NULL) return 0;
                              char* mystr = getLine(f);
                              if(strncmp(name2,mystr,sizeof(name2))>0)
                              {
                                  printf("%s - %s",filename,name2);
                              }
                             return 0;
                             }

main(){
      char* dirname[500];
      char* str = "Заданная строка";
      int size;
      struct dirent **namelist;
      int n = scandir("/proc", &namelist, 0, alphasort);
      if (n < 0){
      perror("scandir");
                }
      else {
           size=n;
           while(n--){
               if(isNum(namelist[n]->d_name)){
                                             dirname[n]=namelist[n]->d_name;
                                             }
                     }
           while(size--){
                        if(sizeof(dirname[size])>0) openfile(dirname[size],str);
                        }

                   }
}

pozitiffcat ★★★
()
Ответ на: комментарий от pozitiffcat

Это не СИ
memset, а не цикл
sizeof(name) == 4(8) байт
и вобще много всего, чего не должно быть.
RTM!!!

rg-400
()

По моему наиболее корректный вариант:

#include <errno.h>
#include <ctype.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


#define DIRFILE    "file.txt"
#define FILESTRING "blabla"


static int have_a_line(const char *dir)
{
    FILE  *fp;
    char   path[256];
    char  *line;
    size_t len = 0;

    snprintf(path, sizeof(path), "%s/" DIRFILE, dir);

    fp = fopen(path, "r");
    if (fp == NULL) {
        return 0;
    }

    if (getline(&line, &len, fp) == -1) {
        perror("getline");
        exit(EXIT_FAILURE);
    }

    if (strncmp(line, FILESTRING, sizeof(FILESTRING)) > 0) {
        free(line);
        return 1;
    }

    free(line);
    return 0;
}


static inline int with_dig(const char *p)
{
    const char *pp = p;
    for(; *p; p++) {
        if (isdigit(*p)) {
            return have_a_line(pp);
        }
    }
    return 0;
}

static inline int dir_with_dig(const struct dirent *d)
{
    if (d->d_type != DT_DIR) {
        return 0;
    }
    return with_dig(d->d_name);
}


static void flow(const char *path)
{
    int i, n;

    struct dirent **namelist;

    n = scandir(path, &namelist, dir_with_dig, alphasort);
    if (n < 0) {
        perror("scandir");
        return;
    }

    for (i = 0; i < n; i++ ){
        printf("%s\n", namelist[i]->d_name);
        free(namelist[i]);
    }

    free(namelist);
}


int main(int argc, char *argv[])
{
    int i;

    if (argc < 2) {
        printf("Usage: %s [path to dir]\n", argv[0]);
        return -1;
    }

    for (i = 1; i < argc; i++) {
        flow(argv[i]);
    }

    return 0;
}
catap ★★★★★
()
Ответ на: комментарий от catap

>По моему наиболее корректный вариант

О, сколько гонору

char path[256];

Узнаю быдлокодера. Откуда вы такие криворукие беретесь?!

ttnl ★★★★★
()
Ответ на: комментарий от ttnl

2 catap:

Перед, тем, как исправлять, рекомендую глянуть сюда, чтобы мне не пришлось снова тыкать тебя в наваленную тобой кучу: http://en.wikipedia.org/wiki/Comparison_of_file_systems#Limits

Судя по всему, ты не имеешь представления о разницы между ограничениями на длину в байтах и в символах.

ttnl ★★★★★
()
Ответ на: комментарий от pozitiffcat
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include<dirent.h>
int isNum(const struct dirent *de){
  char *s = strdup(de->d_name), *ptr;
  ptr = s;
  int r;
  while (isdigit(*ptr)) ptr++;
  r = !*ptr;
  free(s);
  return r;
}
int main(){
FILE* f;
char buf[100];
       int pid,n,i,c;
       char **names;
char way[60]="/proc";
struct dirent **namelist;
n = scandir(way, &namelist, isNum, alphasort);
if (n < 0){
perror("scandir");
          }
else {
names=(char**)malloc(n*sizeof(char*));
for(i=0;i<n;i++){
names[i] = strdup(namelist[i]->d_name);
free(namelist[i]);
                }
     }
free(namelist);


for(i=0;i<n;i++){
printf("%s\n", names[i]);
                }
printf("\n enter 'Name: name procces' : ");

fgets(buf,sizeof(buf),stdin);
if(buf[strlen(buf)-1]=='\n'){
                            buf[strlen(buf)-1]='\0';
                            }
}

не пойму почему после ввода имени процесса выдает ошибку сегментации

suv121
() автор топика
Ответ на: комментарий от suv121

У меня работает. Возможно, у вас какие-то проблемы с переполнением буфера (fgets не контролирует переполнение).

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Попробуйте лучше getline - он динамически выделяет память (или увеличивает размер указанного вами буфера, если его длины не хватает)..

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от suv121

Моя вина: указатель buf не должен быть константой. Т.е. надо, например, так:

char *bb=NULL;
size_t nn;
getline(&bb,&nn,stdin);

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include<dirent.h>
int isNum(const struct dirent *de){
  char *s = strdup(de->d_name), *ptr;
  ptr = s;
  int r;
  while (isdigit(*ptr)) ptr++;
  r = !*ptr;
  free(s);
  return r;
}

int openfile(char* name, char name2[100]){
 char* filename;
 int i,x;
filename=(char*)malloc(256);
 sprintf(filename,"/proc/%s/status", name);
FILE* f=fopen(filename,"r");
 for(x=0;fgetc(f)=='\n';x++){
 filename[x]=fgetc(f);
 }
if(strcmp(name2,filename)==0){
 for(x=0;x<60;x++){
 printf("%s",name2[x]);
 }
 for(x=0;x<60;x++){
 printf("%s",name[x]);
 }
}
free(filename);
fclose(f);
 return 0; }


int main(){
FILE* f;
char buf[100];
       int pid,n,i,c;
       char **names;
char way[60]="/proc";
struct dirent **namelist;
n = scandir(way, &namelist, isNum, alphasort);
if (n < 0){
perror("scandir");
          }
else {
names=(char**)malloc(n*sizeof(char*));
for(i=0;i<n;i++){
names[i] = strdup(namelist[i]->d_name);
free(namelist[i]);
                }
     }
free(namelist);


for(i=0;i<n;i++){
printf("%s\n", names[i]);
                }
printf("\n enter 'Name: name procces' : ");

fgets(buf,sizeof(buf),stdin);
printf("jjhkghskgh");
if(buf[strlen(buf)-1]=='\n'){
                            buf[strlen(buf)-1]='\0';
                            }
printf("heellekleje");
for(i=0;i<n;i++){
openfile(names[i],buf[100]);
          }

free(names);
return 0;
}




fgets работает нормально если закоментить последний цикл for

suv121
() автор топика
Ответ на: комментарий от suv121

А это потому, что ваш openfile дырявый!

Мне лень разбираться. Мой вам совет: не используйте опасные функции! Замените sprintf на snprintf; не делайте так: filename[x]=fgetc(f) (есть же fgets, getline...); после fopen проверяйте, открылся ли файл; scrcmp замените на strncmp.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от suv121

И я вообще не понял, зачем вы считываете первую строку /proc/PID/status? Вы получите строчку «Name: <имя процесса>», и strcmp никогда не даст равенства строк. Ищите уж тогда функцией strstr, или разбейте на токены.

Что вы вообще хотите сделать функцией openfile?

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Если вы хотите найти PID'ы всех процессов с заданным именем, посмотрите на функцию killall, которую я приводил выше. Она как раз этим и занимается.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

ей я хочу считать первую строку из файла , сравнить с заданной , если они равно то вывести её , а под ней написать путь к файлу статус и так пройти по всей директории

suv121
() автор топика
Ответ на: комментарий от suv121

Объясните, для чего вам это нужно: про первую строчку в этих файлах я уже выше говорил.

Короче, полный текст задания к лабораторной работе - в студию.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

мне дано название процесса , нужно сандиром прошарить папку proc, потом открыть каждую и в файлах статус найти названия процессов и сравнить с заданным , процессов может быть несколько , в том числе сама программа может называться так же , убить нужно все кроме той которая убивает

suv121
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.