Запись и замена переменных в текстовом файле на C - PullRequest
0 голосов
/ 25 сентября 2018

Я немного застрял в проекте, которым занимаюсь.Я пытаюсь написать функцию, которая проходит через текстовый файл и сохраняет любые назначения переменных в структуре данных, состоящей из ключа (имя переменной) и данных (данные переменной). Здесь - это проект, если кто-то заинтересован в том, чтобы посмотреть.

До сих пор мне удавалось лишь выполнить индексирование файла и определить, сколько строк содержит равных '='знаки, увеличивающие переменную каждый раз при обнаружении такой строки и использующие переменную для инициализации новой конструкции для хранения переменных.Вот код для функции, названной replaceVariables : (это еще не закончено)

struct VarMap {
    char data[1000];
    char key[1000];
};

// Use a hash table to store the variables - variablename : definition
void replaceVariables(FILE* spData) {

    // Initialise the counting variable buffer to hold the file line by line
    int varCount = 0;
    char buffer[10000];
    while (fgets(buffer , sizeof(buffer) , spData) != NULL) {
        // Skip commented lines (preceede by hash '#')
        if (buffer[0] == '#') continue;
        for (int i = 0; buffer[i] != '\n' ; i++) {
            if (buffer[i] == '=') {
                // Increment if line with equals sign is found
                varCount++;
                break;
            }
        }
    }
    printf ("varCount has counted %d equals signs.\n\n" , varCount);

    // This will hold the variables
    struct VarMap variables[varCount];
    while (fgets(buffer , sizeof(buffer) , spData) != NULL) {
        if (buffer[0] == '#') continue;
        for (int i = 0; buffer[i] != '\n' ; i++) {
            if (buffer[i] == '=') {
                // Store everything before the first equals sign in the key, and everything after the equals sign as data

                break; // We are not interested if the same line contains anymore equals signs
            }
        }
    }


}

Вот функция main для контекста: (это можетздесь важно отметить, что замена переменных не является основной целью программы: готовая программа реализует небольшое подмножество функций, предоставляемых программой make )

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

    char filepath[1000];
    printf("Enter the filepath of the Bakefile or bakefile: ");
    scanf("%s" , filepath);
    FILE* spData = fopen(filepath , "r");
    if (spData == NULL) {
        printf ("Cannot open file.");
        exit(EXIT_FAILURE);
    }
    replaceVariables(spData);

    fclose(spData);
    return 0;
}

Myвопросы:

Как сохранить имя переменной и данные (обозначенные линией со знаком равенства в ней) в структуре, которую я создал?

После сохранения, как мне пройти через файл и заменить все переменные (обозначенные знаком доллара '$' перед скобками вокруг переменной, как $ (VARIABLE)) их определениями?

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Чтобы ответить на первую часть вопроса (я не уверен насчет второй части), просто небольшая модификация вашего кода.Заменить:

   // This will hold the variables
    struct VarMap variables[varCount];
    while (fgets(buffer , sizeof(buffer) , spData) != NULL) {
...

на:

   // This will hold the variables
    struct VarMap variables[varCount];
    int j=0;
    rewind(spData);
    while (fgets(buffer , sizeof(buffer) , spData) != NULL) {
        if (buffer[0] == '#') continue;
        char *p=strstr(buffer,"=");
        if(p){
            *p++=0;
             strncpy(variables[j].key, buffer,1000);
             strncpy(variables[j].data, p,1000);
             j++;
        }
    }

Обновление: чтобы проверить, я добавил еще 2 строки после последнего цикла:

for(int i=0; i<varCount;i++)
        printf("k: %s, v: %s\n",variables[i].key,variables[i].data);

. / A.out

Введите путь к файлу Bakefile или bakefile: Makefile

varCount насчитал 11 знаков равенства.

k: MK_ARCH_DIR?, v: ../

k: CC, v: gcc

k: LDFLAGS, v: -Wl, -rpath, / usr / local / lib -L / usr / local / lib -lNBiometrics -lNCore -lNLicensing

k: CXX, v: g ++

k: CFLAGS +, v: -Wall -I / home / xxx / work / megamatcher / Включить

и т. Д. *

0 голосов
/ 25 сентября 2018

Как сохранить имя переменной и данные (обозначенные линией со знаком равенства) в структуре, которую я создал?

Что-то вроде этого:

int p = 0;
while (buffer[p] != '=') {
    key[p] = buffer[p];
    p++;
}
key[p] = '\0';
strcpy(data, buffer+p+1);

Для ключа мы копируем строку по одному символу за раз, пока не достигнем «=».Вместо этого мы помещаем нулевой терминатор.Для данных мы продолжаем печатать после '='.

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

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

  • Перейти к первому появлению "$ ("
  • Скопируйте все до этого в измененную версию файла
  • Копироватьвсе от "$ (" до следующего ")" в отдельную строку
  • Удалите "$ (" и ")", чтобы получить имя переменной
  • Найдите имя этой переменной в вашемсписок переменных, используя strcmp
  • Добавьте найденную строку в измененный файл
  • Установите курсор на ")" и повторяйте до тех пор, пока не будет сделано

ВещиВозможно, вам придется учитывать, что вы должны проверить символ конца строки.Кроме того, если вы используете strcat для объединения копии, обратите внимание, что время ее выполнения пропорционально размеру обеих строк.Таким образом, если вы добавляете значение переменной в файл, он проходит через весь файл, чтобы найти нулевой терминатор и добавить туда значение.Это не проблема для маленьких файлов, но для больших файлов с большим количеством добавлений, вы можете написать свою собственную функцию конкатенации строк, которая сохраняет позицию нулевого терминатора, так что ему не придется каждый раз искать его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...