Форум программистов, компьютерный форум CyberForum.ru

Поиск с консоли - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 61, средняя оценка - 4.67
^Tecktonik_KiLLeR
 Аватар для ^Tecktonik_KiLLeR
1144 / 426 / 19
Регистрация: 23.06.2009
Сообщений: 6,141
Завершенные тесты: 1
30.09.2009, 21:42     Поиск с консоли #1
вот решил прогу писать,которая ищет на компе все файлы с расширением doc,и все в них удаляет и добавляет звездочки...я только не знаю эту функцию поиска,помогите пожалуйста,надо найти все файлы,и записать их адреса в чар,чтобы потом пользовался с чаром как file_name, наверно понятно объяснилесли возможно то поболше комментарий,ведь с этой функцией в жизни не работалбуду благодарен
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
01.10.2009, 09:31     Поиск с консоли #2
МедведЪ, На всякий случай
TanT
эволюционирую потихоньку
 Аватар для TanT
464 / 462 / 43
Регистрация: 30.06.2009
Сообщений: 1,399
01.10.2009, 09:40     Поиск с консоли #3
в общем делай что думаешь и думай что делаешь !!!
-=ЮрА=-
Заблокирован
Автор FAQ
01.10.2009, 12:21     Поиск с консоли #4
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Вот консольная програмка для поиска файла в директории по его расширению....
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <windows.h>
#include <shlobj.h>
#include <stdio.h>
#include <conio.h>
 
LPTSTR SelectFile();
void GetFileList(LPTSTR sPath, LPTSTR sExt);
 
void main()
{
    bool IsSelected = false;
    char sPath[MAX_PATH];
    char sExt[MAX_PATH];
    sprintf(sPath,"%s","[file_find.exe] Created by -=ЮрА=- 2009");
    CharToOem((LPCTSTR)sPath,sPath);
    SetConsoleTitle(sPath);
    printf("This program help to find files on its extensions *.ext\r\n");
 
    HWND hWnd = FindWindow(NULL, sPath);
    ShowWindow(hWnd,SW_HIDE);
    if(strcpy(sPath,SelectFile()))
        IsSelected = true;
    ShowWindow(hWnd,SW_SHOW);
    if(IsSelected)
    {
        GetShortPathName(sPath,sPath,MAX_PATH);
        printf("Enter extension (*.ext) -> ext :\t");scanf("%s",sExt);
        GetFileList(sPath, sExt);
    }
    printf("For enter new Ext press NUM1\r\n");
    if(getch() == 49)
        main();
}
 
LPTSTR SelectFile()
{
    char sPath[MAX_PATH];sPath[0] = '\0';
    LPCITEMIDLIST lpItemDList;
    BROWSEINFO bi = {NULL, NULL, sPath,
       "Выберите директорию для поиска",
        BIF_DONTGOBELOWDOMAIN/*|BIF_BROWSEINCLUDEFILES*/,
        NULL,
        NULL,
        0
    };
    if((lpItemDList=SHBrowseForFolder(&bi)))
    {
        if(SHGetPathFromIDList(lpItemDList, sPath))
            GetShortPathName((LPCTSTR)sPath,sPath,strlen(sPath));
    }
    return &sPath[0];
}
 
void GetFileList(LPTSTR sPath, LPTSTR sExt)
{
    WIN32_FIND_DATA pFILEDATA;
    GetShortPathName(sPath,sPath,MAX_PATH);
    CharToOem(sPath,sPath);
    printf("\r\n\tStart serching in \r\n[%s]\r\n",sPath);
    OemToChar(sPath,sPath);
    HANDLE hFile = FindFirstFile(strcat(sPath,"\\*.*"),&pFILEDATA);
    if (hFile!=INVALID_HANDLE_VALUE)
    {
        char * chBuf;
        sPath[strlen(sPath) - strlen(strstr(sPath,"*.*"))] = '\0';
        do
        {
            //Пропускаем . и ..
            if
            (
            strlen(pFILEDATA.cFileName) == 1
            &&
            strchr(pFILEDATA.cFileName,'.') !=NULL
            )
            if(FindNextFile(hFile,&pFILEDATA) == 0)
                break;
            if
            (
            strlen(pFILEDATA.cFileName) == 2   
            &&
            strstr(pFILEDATA.cFileName,"..") !=NULL
            )
            if(FindNextFile(hFile,&pFILEDATA) == 0)
                break;
            //
            //Если нашли директорию, запускаем поиск в ней
            //(рекурсивный поиск
            if(pFILEDATA.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                GetFileList(strcat(sPath,pFILEDATA.cFileName), sExt);
            else
            {
                //Проверяем на соотвествие sExt расширения pFILEDATA.cFileName
                if((chBuf = strrchr(pFILEDATA.cFileName,'.')))
                if(strstr(chBuf + 1,sExt))
                {
                    //Если не будем использовать CharToOem()
                    //то на экране русский шрифт каракулями выйдет
                    CharToOem(pFILEDATA.cFileName,pFILEDATA.cFileName);
                    printf("\t\t-> %s\r\n",pFILEDATA.cFileName);
                }
            }
        }
        while (FindNextFile(hFile,&pFILEDATA)!=0);
    }
    printf("\r\n\tSearching complete\r\n",sPath);
}
Миниатюры
Поиск с консоли  
TanT
эволюционирую потихоньку
 Аватар для TanT
464 / 462 / 43
Регистрация: 30.06.2009
Сообщений: 1,399
01.10.2009, 12:32     Поиск с консоли #5
Юоа, хорошая программа, сохраню для досконального изучения.про справочник не забыл, недавно говорили?
-=ЮрА=-
Заблокирован
Автор FAQ
01.10.2009, 12:58     Поиск с консоли #6
Сообщение было отмечено автором темы, экспертом или модератором как ответ
TanT, не забыл, вот выкладываю...
Вложения
Тип файла: rar worldcpp.rar (6.38 Мб, 691 просмотров)
^Tecktonik_KiLLeR
 Аватар для ^Tecktonik_KiLLeR
1144 / 426 / 19
Регистрация: 23.06.2009
Сообщений: 6,141
Завершенные тесты: 1
01.10.2009, 15:44  [ТС]     Поиск с консоли #7
easybudda, блин причем мне тут это?

Добавлено через 32 секунды
-=ЮрА=-, а что то попроще нету?
-=ЮрА=-
Заблокирован
Автор FAQ
01.10.2009, 16:13     Поиск с консоли #8
Что именно упростить?Можно диалог выбора каталога убрать и вводить каталог с клавы или тектового файла, а вот алгоритм поиска файлов я думаю никак проще и не сделать (утверждать не стану)...
Тут наверно более опытные програмеры уже должны помочь...
^Tecktonik_KiLLeR
 Аватар для ^Tecktonik_KiLLeR
1144 / 426 / 19
Регистрация: 23.06.2009
Сообщений: 6,141
Завершенные тесты: 1
01.10.2009, 17:27  [ТС]     Поиск с консоли #9
-=ЮрА=-, мне нужен только поиск,ненадо чтобы выводлилось все это.
^Tecktonik_KiLLeR
 Аватар для ^Tecktonik_KiLLeR
1144 / 426 / 19
Регистрация: 23.06.2009
Сообщений: 6,141
Завершенные тесты: 1
09.10.2009, 23:19  [ТС]     Поиск с консоли #10
-=ЮрА=-, все еще ответов нету?
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,266
08.11.2009, 22:41     Поиск с консоли #11
Взялся за анализ исходника. Там есть куда дорабатывать. Так, имеем допустим, директорию C:\proba, в которой, в свою очередь есть 5 (к примеру) директорий без файлов с расширением exe
Предположим также, что мы ищем файлы именно с таким расширением.
Тогда вывод будет таким.


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        Start serching in
[C:\proba\proba_1]
 
        Searching complete
 
        Start serching in
[C:\proba\proba_1\proba_2]
 
        Searching complete
 
        Start serching in
[C:\proba\proba_1\proba_2\*.*proba_3]
 
        Searching complete
 
        Start serching in
[C:\proba\proba_1\proba_2\*.*proba_3\*.*proba_4]
 
        Searching complete
 
        Start serching in
[C:\proba\proba_1\proba_2\*.*proba_3\*.*proba_4\*.*proba_5]
Неправильно, я считаю.
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,266
09.11.2009, 02:38     Поиск с консоли #12
МедведЪ, ты просил. Упрощённый вариант проги -=ЮрА=-


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <windows.h>
#include <stdio.h>
 
void GetFileList(LPTSTR sPath, LPTSTR sExt);
 
int main(){
        char sPath[MAX_PATH];
        char sExt[MAX_PATH];
 
                printf("Enter directory  :\t");scanf("%s", sPath);
                printf("Enter extension (*.ext) -> ext :\t");scanf("%s",sExt);
                GetFileList(sPath, sExt);
 system ("PAUSE");
}
 
void GetFileList(LPTSTR sPath, LPTSTR sExt) {
 
 WIN32_FIND_DATA pFILEDATA;
 
 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!Закомментил это!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 //GetShortPathName(sPath,sPath,MAX_PATH);
 CharToOem(sPath,sPath);
 printf("\r\n\tStart serching in \r\n[%s]\r\n",sPath);
 OemToChar(sPath,sPath);
 HANDLE hFile = FindFirstFile(strcat(sPath,"\\*.*"),&pFILEDATA);
 if (hFile!=INVALID_HANDLE_VALUE)    {
  char * chBuf;
  sPath[strlen(sPath) - strlen(strstr(sPath,"*.*"))] = '\0';
  do {
   //Пропускаем . и ..
   if (strlen(pFILEDATA.cFileName) == 1 &&  strchr(pFILEDATA.cFileName,'.') !=NULL)
    if (FindNextFile(hFile,&pFILEDATA) == 0)
      break;
   if (strlen(pFILEDATA.cFileName) == 2 && strstr(pFILEDATA.cFileName,"..") !=NULL)
    if(FindNextFile(hFile,&pFILEDATA) == 0)
      break;
     //Если нашли директорию, запускаем поиск в ней рекурсивный поиск
   if(pFILEDATA.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
     GetFileList(strcat(sPath,pFILEDATA.cFileName), sExt);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!оБЯЗАТЕЛЬН востанавливать дллину пути................................     
     sPath[strlen(sPath) - strlen(pFILEDATA.cFileName)- 1] = '\0';
   }
   else {
    //Проверяем на соотвествие sExt расширения pFILEDATA.cFileName
    if((chBuf = strrchr(pFILEDATA.cFileName,'.'))) {
     if(strstr(chBuf + 1,sExt)) {
      //Если не будем использовать CharToOem() то на экране русский шрифт каракулями выйдет
      CharToOem(pFILEDATA.cFileName,pFILEDATA.cFileName);
      printf("\t\t-> %s\r\n",pFILEDATA.cFileName);
     }
    }
   }
  }
  while (FindNextFile(hFile,&pFILEDATA)!=0);
 }
 printf("\r\n\tSearching complete\r\n",sPath);
}
-=ЮрА=-, там в проге была одна принципильная, на мой взгляд ошибка. По возвращению из функции ты забыл восстанавливать длину пути. Поэтому каждый раз путь увеличивался и увеличивался, прибавляя пройденный папки и не "скидывая"

Потом, я закомментил возврат короткого пути.
В тексте я всё это пометил.

Вроде остальное правильно.
Тебе вопрос: скажи пожалуйста за константу FILE_ATTRIBUTE_DIRECTORY
Какова её роль? Не могу понять.
Спасибо.

Добавлено через 1 минуту
Да ещё. Кто будет использвать- о заголовочнх файлах и перетипизации данных заботьтесь сами, я такие мелочи даже не упоминал.

Добавлено через 8 минут
И второй вопрос
Юра, ты располагаешь сведениями, в каком порядке ищутся файлы?
TanT
эволюционирую потихоньку
 Аватар для TanT
464 / 462 / 43
Регистрация: 30.06.2009
Сообщений: 1,399
09.11.2009, 09:06     Поиск с консоли #13
хм, странно, я, конечно, не вникал особо, но Юра выкладывал уже этот код некоторое время назад, за что ему большое спасибо.
Я успешно воспользовался данным примером, сейчас полез и проверил ищет все файлы (сделал в коневой папке 3 папки и в каждой из этих трёх ещё по несколько и все файлы нашлись.)
Там ведь рекурсивный вызов GetFileList.
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,266
09.11.2009, 12:15     Поиск с консоли #14
Так искать-то, он, может, и ищет, а ты попробуй создать пустую папку C:\proba и в ней создай пять папки proba_1 proba_2 proba_3 proba_4 proba_5 и наполни их каким-нибудь содержимым- например, текстовыми файлами. Или оставь пустыми, это неважно.

А потом попробуй найди в папке C:\proba файлы, которых в ней заведомо нет и во вложенных папках тоже нет.
И посмотри на вывод

...И это. Перед заходом в каждую директорию соответственно изменялся (увеличивался путь) директории
C++
1
GetFileList(strcat(sPath,pFILEDATA.cFileName), sExt);
А по выходу из этой рекурсивной функции этот путь не был восстановлен, как ни крути.
А восстанавливать его надо. Отнимать то есть имя директории, поиск в которой мы
только что закончили. Так что вот.

Добавлено через 12 минут
И вывод выложи, если можно.

Добавлено через 22 минуты
Я те больше скажу- не поленись, помести в папку proba_5 файл *exe и попробуй его найди в папке C:\proba
Не найдёт. Догадываешься, почему? Потому, что в проге не присутствует строки
C++
1
C:\proba\proba_5
Вместо неё
C++
1
C:\proba\proba_1\proba_2\*.*proba_3\*.*proba_4\*.*proba_5
Что, конечно же, ошибка.
TanT
эволюционирую потихоньку
 Аватар для TanT
464 / 462 / 43
Регистрация: 30.06.2009
Сообщений: 1,399
09.11.2009, 12:22     Поиск с консоли #15
с выводом хуже, честно признаюсь не знаю как с консоли его содрать.
да и вывод там смешан с моей отладкой, но результат у меня такой: как вы, kravam, и говрили сделал кучу пустых вложенных папок запихал туда разное и искал чего нет соответсвенно ничего не нашёл. добавил фаил который попадает в условия по иска и нашел его.
однако, наш диалог не принесёт результата, так как я уже не помню редактировал ли я Юрины исходники или нет и выдрать их из моего проекта возможноти и желания не имею. одно тока скажу что работает данный блок в моем проекте правильно, покрайней мере в данном частном случае.
я тоже заинтересован в создании правильного кода поиска файлов.
Юра ты где? разреши вопрос.
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,266
09.11.2009, 12:36     Поиск с консоли #16
Проще будет скомпилить НЕПОСРЕДСТВЕННО Юрину программу. Ошибка в ней. А не в другой проге.
Ну, или дождаться Юру, я ему уже написал.
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,266
09.11.2009, 19:39     Поиск с консоли #17
МедведЪ, вот тебе ещё проще.
Вариант Юриной проги.
Ничего вводить не надо.
Забиваешь в исходник имя директории, расширение (обрати внимание на размер) и смотришь на вывод.
Хочешь, звпускай из командной строки и перенаправляй в файл. Открыть надо в кодировке OEM (Она же MS DOS)

В выводе увидишь исключительно имена файлов с полными путями. Всё! Ничего больше.
Делай с ними, что хочешь.


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <windows.h>
#include <stdio.h>
 
void GetFileList(LPTSTR sPath, LPTSTR sExt);
 
int main(){
 
//Поскольку sPath и sExt одинаковы во всех вызовах GetFileList, их можно было бы сделать
//глобальными, но я так оставил. 
        char sPath[MAX_PATH]= "C:\\vso_moio";
        char sExt[4]= "exe";
        GetFileList(sPath, sExt);
  system ("PAUSE");
}
 
void GetFileList(LPTSTR sPath, LPTSTR sExt) {
 
 WIN32_FIND_DATA pFILEDATA;
 
 HANDLE hFile = FindFirstFile(strcat(sPath,"\\*.*"),&pFILEDATA);
 if (hFile!=INVALID_HANDLE_VALUE)    {
  char * chBuf;
  sPath[strlen(sPath) - strlen(strstr(sPath,"*.*"))] = '\0';
  do {
   //Пропускаем . и ..
   if (strlen(pFILEDATA.cFileName) == 1 &&  strchr(pFILEDATA.cFileName,'.') !=NULL)
    if (FindNextFile(hFile,&pFILEDATA) == 0)
      break;
   if (strlen(pFILEDATA.cFileName) == 2 && strstr(pFILEDATA.cFileName,"..") !=NULL)
    if(FindNextFile(hFile,&pFILEDATA) == 0)
      break;
     //Если нашли директорию, запускаем поиск в ней рекурсивный поиск
   if(pFILEDATA.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
     GetFileList(strcat(sPath,pFILEDATA.cFileName), sExt);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!оБЯЗАТЕЛЬН востанавливать дллину пути................................     
     sPath[strlen(sPath) - strlen(pFILEDATA.cFileName)- 1] = '\0';
   }
   else {
    //Проверяем на соотвествие sExt расширения pFILEDATA.cFileName
    if((chBuf = strrchr(pFILEDATA.cFileName,'.'))) {
     if(strstr(chBuf + 1,sExt)) {
      //Если не будем использовать CharToOem() то на экране русский шрифт каракулями выйдет
      CharToOem(sPath,sPath);
      printf("\n\n%s",sPath);
      OemToChar(sPath,sPath);
      CharToOem(pFILEDATA.cFileName,pFILEDATA.cFileName);
      printf("%s\r\n",pFILEDATA.cFileName);
     }
    }
   }
  }
  while (FindNextFile(hFile,&pFILEDATA));
 }
}
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,266
11.11.2009, 07:38     Поиск с консоли #18
Друзья!
Если кто пользуется вышеприведёнными прогами быстренько взяли и поправили исходник.
Там ошибка есть, что у Юры, что у меня, я щас только нашёл.
Вот эту строку
C++
1
sPath[strlen(sPath) - strlen(strstr(sPath,"*.*"))] = '\0'
Надо выполнять не по условию, а НЕЗАВИСМО ВЫПОЛНЯЕТСЯ УСЛОВИЕ ИЛИ НЕТ!
Если пропишем после if (как делали до сего момента), то тогда, если вдруг натыкаемся на
системную директорию или файл, то FindFirstFile возвращает -1. Следовательно, всё,
что выполнняется по условию (hFile!=INVALID_HANDLE_VALUE) не выполнится и в частности,
не будет поставлен конец строки!
А это значит, что по выходу из рекурсивной функции GetFileList в том месте, где мы
восстанавливаем длину, она будет восстановлена неправильно.

Я наткнулся на директорию System Volume Information, не обработал её таким образом,
а потом , когда восстанавливал путь, он у меня восстанвился не как C:\ а как
C:\Sys!

Прибавились эти злополучные три байта, которые я не "отсёк" , не поставил ноль сюда
С:\System Volume Informationвот в это место надо ставить ноль!\*.*

Поэтому поправьте так:

C++
1
2
3
4
5
6
7
8
9
10
11
void GetFileList(LPTSTR sPath, LPTSTR sExt, LPTSTR sEXT) {
 WIN32_FIND_DATA pFILEDATA;
 HANDLE hFile = FindFirstFile(strcat(sPath,"\\*.*"),&pFILEDATA);
 
 //!!!!!!!!!!!!!!!!!!!!!!
 sPath[strlen(sPath) - strlen(strstr(sPath,"*.*"))] = '\0';
 //!!!!!!!!!!!!!!!!!!!!!!!
 
 if (hFile!=INVALID_HANDLE_VALUE)    {
  char * chBuf;
  do {
Вроде всё.
-=ЮрА=-
Заблокирован
Автор FAQ
11.11.2009, 10:10     Поиск с консоли #19
Медведъ, я не могу понять что именно тебе не надо выводить?Результатом поиска файлов являются их пути или хэндлы, куда тебе их выводить в файл, сделать символьный двухмерный массив???В моей проге пути на экран выводятся...
Что же касается поиска то цикл do while в программе и выполняет поиск...FindNextFile - это функция поиска файла для каталога в котором FindFirstFile вернула хэндл первого файла
Детально сформулируй задание, помогуЛучше даже нарисуй интерфейс и как образец сюда выставь, а я попробую его реализовать...

Добавлено через 9 минут
kravam , если у тебя файловая система NTFS то действительно прога на System Volume Information споткнётся, а вот на фате всё работает, ну а данную манипуляцию sPath[strlen(sPath) - strlen(strstr(sPath,"*.*"))] = '\0'; я делаю по следующей причине :
ИмяКаталога\ -> припаиваем к нему "*.*" -> Выходит ИмяКаталога\*.* если в данном каталоге есть файлы то заходим в цикл в котором функция FindNextFile(hFile,&pFILEDATA) постоянно переинициализирует структуру WIN32_FIND_DATA pFILEDATA, а теперь если я бы не убрал данные символы "*.*" из имени каталога то получал бы такие пути ИмяКаталога\*.*\pFILEDATA.cFileName
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.11.2009, 10:10     Поиск с консоли
Еще ссылки по теме:

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

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
^Tecktonik_KiLLeR
 Аватар для ^Tecktonik_KiLLeR
1144 / 426 / 19
Регистрация: 23.06.2009
Сообщений: 6,141
Завершенные тесты: 1
11.11.2009, 10:10  [ТС]     Поиск с консоли #20
-=ЮрА=-, Oo какой интерфейс...я же сказал,осущствить список по компу doc файлов(что уже есть) и изменить весь тет на "*"...этого то нет
Yandex
Объявления
11.11.2009, 10:10     Поиск с консоли
Закрытая тема Создать тему
Опции темы

Текущее время: 10:25. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru