Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
SadiQ228
10 / 10 / 6
Регистрация: 16.12.2016
Сообщений: 343
1

По файлу с программой на языке С выполнить все директивы #include (могут быть вложены)

17.04.2018, 01:03. Просмотров 218. Ответов 12
Метки нет (Все метки)

Есть три файла:
soft.cpp:
C
1
2
3
4
5
#include "test1.h"
int main (void)
{
funct();
}
test1.h:
C
1
2
void funct();
#include "test2.h"
test2.h:
C
1
2
3
4
funct
{
printf("Hello");
}


Программа обращаясь к первому файлу, должна выдать файл:
C
1
2
3
4
5
6
7
8
9
void funct();
funct
{
printf("Hello");
}
int main (void)
{
funct();
}
как реализовать проверку и вывод вложенных инклудов?
при открытии файла "stdafx.h" в буфер приходит "яю/KE @51CNI85AO" остальные файлы читает даже с русскими буквами.
Прошу подсказок даже без кода а на словах, вложенность не сделать рекурсией потому что придется открывать один и тот же файл не закрывая поток. не понимаю как сделать лучше?
Вот мой код, который уже работает почти, пусть к папке с файлами храниться в переменной path2project
гляньте кому не трудно
Кликните здесь для просмотра всего текста
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "stdafx.h"
#include "my_lab.h"
#include <string.h>
void GetPath(char*buf, char*path2project, char*NewPath);
void CopyFile2File(char*NewPath, char*OutFilePath);
void FileCombo(char*TmpFilePath, char*OutFilePath);
 
void GetPath(char*buf, char*path2project, char*NewPath)
{
    unsigned int i, j;
    char FileName[BufSize] = { 0 };
    //имя файла
    for (i = 0, j = 0; i < BufSize; i++)
    {
        if (buf[i] == '"')
        {
            i++;
            while (buf[i] != '"')
            {
                FileName[j++] = buf[i++];
            }
            FileName[j] = '\0';
        }
    }
    //новый путь
    for (i = 0, j = 0; path2project[j]; i++)
    {
        NewPath[i] = path2project[j++];
    }
    for (j = 0; j<strlen(FileName); i++)
    {
        NewPath[i] = FileName[j++];
    }
    NewPath[i] = '\0';
    printf("%s\n", NewPath);
}
 
void CopyFile2File(char*NewPath, char*OutFilePath)
{
    char * bufferPtr;
    char buffer[BufSize];
    FILE * NewFile, *OutFile;
    errno_t OpenError;
    OpenError = fopen_s(&NewFile, NewPath, "rt");
    OpenError = fopen_s(&OutFile, OutFilePath, "a+");
    if (NewFile == NULL || OutFile == NULL) { printf("FILE OPEN: ERROR"); }
    else
    {
        while (!feof(NewFile))
        {
            bufferPtr = fgets(buffer, sizeof(buffer), NewFile);
            fprintf(OutFile, "%s", buffer);
        }
        fprintf(OutFile, "\n");
    }
    fclose(NewFile);
    fclose(OutFile);
}
 
void FileCombo(char*TmpFilePath, char*OutFilePath)
{
    char * bufPtr;
    char buf[BufSize];
    FILE *FileWithInclude, *FileWithCode;
    errno_t OpenError;
    OpenError = fopen_s(&FileWithCode, TmpFilePath, "rt");
    OpenError = fopen_s(&FileWithInclude, OutFilePath, "a+");
    if (FileWithCode == NULL || FileWithInclude == NULL) { printf("FILE OPEN: ERROR"); }
    else
    {
        while (!feof(FileWithCode))
        {
            bufPtr = fgets(buf, sizeof(buf), FileWithCode);
            fprintf(FileWithInclude, "%s", buf);
        }
        fprintf(FileWithInclude, "\n");
    }
    fclose(FileWithInclude);
    fclose(FileWithCode);
    //remove(TmpFilePath);
    printf("TMP FILE DELETE: OK\n");
}
 
char TmpFilePath[BufSize] = "C:\\Users\\work\\Desktop\\TMP.txt";
char OutFilePath[BufSize] = "C:\\Users\\work\\Desktop\\OUTPUT.txt";
char path2project[BufSize] = "C:\\Users\\work\\source\\repos\\my_lab8\\my_lab8\\\0";
 
 
int main()
{
 
    char NewPath[BufSize];
 
    char * bufPtr;
    char buf[BufSize];
    FILE * myfile1, * myfile2;
    errno_t OpenError;
    OpenError = fopen_s(&myfile1, "C:\\Users\\work\\source\\repos\\my_lab8\\my_lab8\\my_lab.cpp", "rt");
    OpenError = fopen_s(&myfile2, TmpFilePath, "wt");
    if (myfile1 == NULL||myfile2 == NULL){printf("TMP FILE OPEN: ERROR");}
    else
    {
        printf("TMP FILE OPEN: OK\n");
        while (!feof(myfile1))
        {
            bufPtr = fgets(buf, sizeof(buf), myfile1);
            if(buf[0] == '#' && buf[1]=='i')
            {
                printf("INCLUDE FOUND: ");
                GetPath(buf, path2project, NewPath);
                CopyFile2File(NewPath, OutFilePath);
            }
            else
            {
                fprintf(myfile2, "%s", buf);
            }
        }
        printf("TMP FILE COPY: OK");
    }
    printf("\n");
    fclose(myfile1);
    fclose(myfile2);
    printf("TMP FILE CLOSE: OK\n");
    FileCombo(TmpFilePath, OutFilePath);
    return 0;
}


Добавлено через 8 минут
ЗАБЫЛ СКАЗАТЬ РАБОТАЕМ ТОКА С файлами из проекта, не берем стандартные библиотеки
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.04.2018, 01:03
Ответы с готовыми решениями:

По символьному файлу с программой на языке С создать новый файл c именами всех многомерных массивов
/* Во всех программах использовать функции fopen(), fclose(), fgets() ! По...

Заменить директивы include на содержимое входного файла
Здравствуйте. Вот моя задача: Программа обрабатывает текст некой программы на...

Заменить директивы препроцессора #include на содержимое включаемого файла
Вот текст задачи: Программа обрабатывает текст некой программы на C/C++ и...

Каким образом переменные, описанные в одном файле, могут быть доступны другому файлу?
помогите пожалуйста ответить на вопрос 1. Каким образом переменные, описанные...

В строке записан текст на русском языке. В составе текста могут быть целые десятичные числа без знака. Для записи слов используются как прописные, та
В строке записан текст на русском языке. В составе текста могут быть целые...

12
SadiQ228
10 / 10 / 6
Регистрация: 16.12.2016
Сообщений: 343
18.04.2018, 19:33  [ТС] 2
можно ли открыть файл рекурсивно?
0
Старый воин
69 / 69 / 19
Регистрация: 16.08.2017
Сообщений: 156
Записей в блоге: 1
18.04.2018, 21:01 3
Здравствуйте!
Не совсем понятно, что надо... Растащить функции программы по отдельным файлам и собрать проект как многофайловый?
0
SadiQ228
10 / 10 / 6
Регистрация: 16.12.2016
Сообщений: 343
18.04.2018, 21:15  [ТС] 4
нет в многофайловом проекте прочитать файл с инклудом, и вставить его перед кодом! тоесть выполнить элементарные действия препроцессора обратите внимание на первый пост там пример наглядный достаточно
0
Старый воин
69 / 69 / 19
Регистрация: 16.08.2017
Сообщений: 156
Записей в блоге: 1
18.04.2018, 22:08 5
SadiQ228, да, точно, прочитал не внимательно.
Цитата Сообщение от SadiQ228 Посмотреть сообщение
при открытии файла "stdafx.h" в буфер приходит "яю/KE @51CNI85AO"
Этот файл Visual Studio создает - может быть с кодировкой поэтому проблемы?
А Вы не рассматривали вариант построения содержимого выходного файла в выделенной для этого памяти (стандартный препроцессор кажется так и делает), а потом уже в файл записать? Так наверное и рекурсивно открывать файлы получиться.
0
SadiQ228
10 / 10 / 6
Регистрация: 16.12.2016
Сообщений: 343
19.04.2018, 01:48  [ТС] 6
не знаю как это сделать

Добавлено через 3 часа 7 минут
как реализовать подсчет и проверку вложенных инклудов? пока что делаю только так, но это не выход, вложений может быть хоть 5 хоть 10

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
void CopyFile2File(char*NewPath, char*OutFilePath, char*path2project)
{
    char * bufferPtr, *AddedIncludePtr1, *AddedIncludePtr2;
    char buffer[BufSize];
    FILE * NewFile, *OutFile, *AddedIncludeFile1, *AddedIncludeFile2;
    errno_t OpenError;
    OpenError = fopen_s(&NewFile, NewPath, "rt");
    OpenError = fopen_s(&OutFile, OutFilePath, "a+");
    if (NewFile == NULL) { printf("FILE OPEN: ERROR"); }
    else
    {
        while (!feof(NewFile))
        {
            bufferPtr = fgets(buffer, sizeof(buffer), NewFile);//читаем по строчно
            if (buffer[0] == '#' && buffer[1] == 'i')          //если видим 
            {
                printf("INCLUDE FOUND: ");
                GetPath(buffer, path2project, NewPath);          //получаем путь
                OpenError = fopen_s(&AddedIncludeFile1, NewPath, "rt"); //открываем
                while (!feof(AddedIncludeFile1))
                {
                    AddedIncludePtr1 = fgets(buffer, sizeof(buffer), AddedIncludeFile1);//читаем по строчно
                    if (buffer[0] == '#' && buffer[1] == 'i')                           //если видим 
                    {
                        printf("INCLUDE FOUND: ");
                        GetPath(buffer, path2project, NewPath);                        //получаем путь
                        OpenError = fopen_s(&AddedIncludeFile2, NewPath, "rt");        //открываем
                        while (!feof(AddedIncludeFile2))
                        {
                            AddedIncludePtr2 = fgets(buffer, sizeof(buffer), AddedIncludeFile2);//читаем по строчно
                            fprintf(OutFile, "%s", buffer);                                     //копируем
                        }
                        fclose(AddedIncludeFile2);
 
                    }
                    else
                    {
                        fprintf(OutFile, "%s", buffer); //копируем
                    }
                }
 
                fclose(AddedIncludeFile1);
            }
            else
            {
                fprintf(OutFile, "%s", buffer); //копируем
            }
        }
 
    }
    fclose(NewFile);
    fclose(OutFile);
}
0
Старый воин
69 / 69 / 19
Регистрация: 16.08.2017
Сообщений: 156
Записей в блоге: 1
19.04.2018, 09:36 7
Вот, на скорую руку псевдокод рекурсивной функции набросал... Возможно ошибки есть. Ну, а сама идея надеюсь понятна будет
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
bool foo(string str)
{
    if(str.length()==0)
    {
        return true;
    }
    else
    {
        ifstream fi(str);
        while(!fi.eof())
        {
            if(строка начинается с "#")
            {
                //здесь проверяем директиву
                if(директива "include")
                {
                    //здесь получаем путь к файлу
                    string s="путь к файлу";
                    foo(s);
                }
            }
            else
            {
                //пишем строку в выходной файл (или в память)  
            }
        }
        fi.close();
        return true;
    }
}
Добавлено через 2 минуты
Более подробно смогу проверить только вечером.
1
SadiQ228
10 / 10 / 6
Регистрация: 16.12.2016
Сообщений: 343
19.04.2018, 20:35  [ТС] 8
тока пришел домой , щас буду пробовать
0
SadiQ228
10 / 10 / 6
Регистрация: 16.12.2016
Сообщений: 343
21.04.2018, 00:40  [ТС] 9
моя новая функция работает, но не читает вложенные инклуды, мое сердце чует, что ошибка связанна с многократным открытием файла OUTPUT который распологается по пути OutFilePath.(что подтверждает принтф)
прошу помощи, быть может его передать в функцию из мэйна? или как поступить то похитрее? прилогаю код!
P.S. пользоваться можно только fopen И fgets

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
void foo(char*NewPath, char*OutFilePath, char*path2project)
{
    char*buf;
    char bufer[BufSize];
    FILE * file1, *file2;
    errno_t OpenError;
    OpenError = fopen_s(&file1, NewPath, "rt");
    OpenError = fopen_s(&file2, OutFilePath, "a+");
    if (file1 == NULL || file2 == NULL) { printf("FILE OPEN: ERROR IN FOO FUNCTION");}
    else
    {
        while (!feof(file1))                                             //читаем пока не конец
        {
            buf = fgets(bufer, sizeof(bufer), file1);         //получаем построчно в буфер
            if (FindInclude(bufer))                               //проверяем строчку на наличие инклуда
            {
                GetPath(bufer, path2project, NewPath); //получаем путь к файлу инклуда
                foo(NewPath,OutFilePath,path2project);
            }
            else
            {
                fprintf(file2, "%s", bufer);                     //копируем в файл аутпут
            }
        }
        fclose(file1);
        fclose(file2);
    }
}
0
Strealht
2 / 2 / 3
Регистрация: 02.03.2015
Сообщений: 38
21.04.2018, 02:30 10
Цитата Сообщение от SadiQ228 Посмотреть сообщение
OpenError = fopen_s(&file1, NewPath, "rt");
что такое "rt"

Кликните здесь для просмотра всего текста
В дополнение к указанным выше значениям, в параметр mode можно добавить следующие символы, чтобы задать режим преобразования для символов новой строки:

t
Откройте файл в текстовом (переведенном) режиме. В этом режиме CTRL+Z интерпретируется как символ конца файла на входе. В файлах, открытых для чтения/записи с использованием режима "a+", fopen_s проверяет наличие символа CTRL+Z в конце файла и удаляет его, если это возможно. Это делается потому, что использование функций fseek и ftell для перемещения в пределах файла, который заканчивается символом CTRL+Z, может вызвать неправильное поведение fseek вблизи конца файла.
0
SadiQ228
10 / 10 / 6
Регистрация: 16.12.2016
Сообщений: 343
21.04.2018, 02:35  [ТС] 11
RT это Read Like Text
есть что по делу?

везде где я видел примеры в функцию передают объект ifstream

но у меня даже при
#include <iostream>
#include <fstream>
объект ifstream ifile("/home/kroplik/t.txt"); - подчеркивает красным....
почему?

Добавлено через 1 минуту
сейчас решение моей проблемы мне видится лишь передачей в функцию файла открытого для дозаписи... не могу этого сделать примеры не работают почему то
0
Strealht
2 / 2 / 3
Регистрация: 02.03.2015
Сообщений: 38
21.04.2018, 03:04 12
http://https://msdn.microsoft.com/ru-ru/library/z5hh6ee9.aspx

Прочитай внимательно ты так не правильно указал параметры.
0
SadiQ228
10 / 10 / 6
Регистрация: 16.12.2016
Сообщений: 343
21.04.2018, 03:10  [ТС] 13
каким то невероятным чудом мой код заработал) чудеса да и только) отрабатывает все вложенные инклуды без буксов) работает быстро)

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
void foo(char*NewPath, FILE **myfile3, char*path2project)
{
    char*buf;
    char bufer[BufSize];
    FILE * file1, *file2;
    errno_t OpenError;
    OpenError = fopen_s(&file1, NewPath, "rt");
    if (file1 == NULL) { printf("FILE OPEN: ERROR IN FOO FUNCTION"); }
    else
    {
        while (!feof(file1))                                         
        {
            buf = fgets(bufer, sizeof(bufer), file1);        
            if (FindInclude(bufer))                             
            {
                GetPath(bufer, path2project, NewPath);
                foo(NewPath, myfile3, path2project);
            }
            else
            {
                fprintf(*myfile3, "%s", bufer);
            }
        }fprintf(*myfile3, "\n");
 
        fclose(file1);
    }
}
Добавлено через 2 минуты
Старый воин, спасибо вам
0
21.04.2018, 03:10
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.04.2018, 03:10

C++ и директивы include c пространством имён
Всем привет! Я только начал изучать C++:-[, в связи с этим появились вопросы:...

"В поле может быть введено только одно слово, пробелы могут быть или не быть с начала слова и в конце"
Добрый вечер уважаемые форумчане. Подскажите как написать выражение со след...

Как пропукать только директивы #include из потока ввода?
Нужна помощь с регулярными выражениями. Вроде бы все просто, а вроде бы и нет....


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru