Попытка создать простую C-программу для редактирования 1 строки в текстовом файле. - PullRequest
2 голосов
/ 03 февраля 2012

Я пытаюсь создать исполняемый файл C, который будет просто переключать строку в моем файле hosts.

например. изменить это:

74.125.224.72 asdf.com www.asdf.com

к этому:

#74.125.224.72 asdf.com www.asdf.com

и обратно.

Это облегчает переключение между версией разработки для веб-сайта и версией в реальном времени. Мне удалось выяснить, как добавить файл, но у меня возникают проблемы при сравнении каждой строки со строкой, которую я ищу, и я также не знаю, как заменить строку в файле. Тестовая программа, которую я вставляю ниже, редактирует «test.txt» на моем рабочем столе. Я не могу получить совпадение строк в цикле while для совпадения с чем-либо.

Вот код:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLINE 50
int main(int argc, char* argv[])
{
    FILE *ifp, *ofp;

    ifp = fopen("C:/Users/Buttle/Desktop/test.txt","a+");
    if (ifp == NULL) {
        printf("Dang it didn't work!\n");
    }

    else printf("Dang it did work!\n");

    char line[MAXLINE];

    int linnum = 1;
    while ((fgets(line,MAXLINE,ifp) != NULL)) {
        printf("line number %d\n" , linnum++);      
        if (line == "74.125.224.72") {
            fputs("#74.125.224.72 asdf.com www.asdf.com",stdout);
        } else if (line == "#74.125.224.72"){
            fputs("74.125.224.72 asdf.com www.asdf.com",stdout);
        } else fputs("We ain't found sh--.",ifp);
    }
    return 0;
}

Ответы [ 6 ]

2 голосов
/ 03 февраля 2012

Сначала вам понадобятся два файла (или вам потребуется реализовать буфер для чтения всего этого). Итак:

ifp = fopen("C:/Users/Buttle/Desktop/test.txt","r"); // Why use a+?
ofp = fopen("C:/Users/Buttle/Desktop/test.txt","w"); // Or use output to std

И давайте сделаем это более общим для вас:

// This will contain list of all ips that you want to handle
typedef const char * cstr;
cstr blacklist[] = {
    "1.2.3.4",
    "5.6.7.8",
    NULL
};


int i;
unsigned char comment; // This is bool
while ((fgets(line,MAXLINE,ifp) != NULL)) {
    i = 0;
    comment = 0;
    while( blacklist[i] != NULL){
        if( strncmp( blacklist[i], line, strlen( blacklist[i]) == 0){
             comment = 1;
             break;
        }
        i++;
    }

    if( comment){
        fprintf( ofp, "#%s\n", line);
    } else {
        fprintf( ofp, "%s\n", line);
    }
}

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

0 голосов
/ 10 февраля 2012

Мой друг помог мне найти решение, поэтому я опубликую его здесь. Самое странное, что я попробовал на нескольких разных установках Windows 7, и это работало немного по-другому. По моему, он работает только в том случае, если я запускаю его, щелкая правой кнопкой мыши и выбирая «Запуск от имени администратора», тогда как в другой установке работает простой двойной щелчок. Это неожиданно, потому что файл hosts должен быть защищен операционной системой.

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

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

Вот оно:

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

#define FILENAME "C:\\Windows\\System32\\drivers\\etc\\hosts"
//#define FILENAME "asdf.txt"

int finder(char * Old_String, char * Find_String);
char * replacer(int replace_point, char * Old_String, char * Replace_String, int find_length);

int finder(char * Old_String, char * Find_String)
{
    //printf("\nOld String: \n%s \n\n\n", Old_String);
    //printf("\nFind String: \n%s \n\n\n", Find_String);
    int old_length = strlen(Old_String);
    int find_length = strlen(Find_String);
    //int replace_length = strlen(Replace_String);
    if (old_length == 0) printf("Old String is empty");
    if (find_length == 0) printf("Find String is empty");
    //if (replace_length == 0) printf("Replace String is empty");
    int replace_point = 0;
    while (replace_point < old_length)
    {
        if ((Old_String[replace_point] == Find_String[0]) && (old_length - replace_point >= find_length))
        {
            int compare_point = 0;
            int This_Found = 1;
            while (compare_point < find_length)
            {
                if (Old_String[replace_point + compare_point] != Find_String[compare_point]) This_Found = 0;
                compare_point ++;
            }
            if (This_Found == 1) break;
        }
        replace_point ++;
    }
    if (replace_point == old_length) return -1;
    else return replace_point;
}

char * replacer(int replace_point, char * Old_String, char * Replace_String, int find_length)
{
    int before_length = replace_point;
    int old_length = strlen(Old_String);
    int replace_length = strlen(Replace_String);
    int after_length = old_length - before_length - find_length;
    int new_length = before_length + replace_length + after_length;
    char * Before_String = (char *) malloc(before_length);
    char * After_String = (char *) malloc(after_length);
    char * New_String = (char *) malloc(new_length);
    memcpy(Before_String, Old_String, before_length);
    memcpy(After_String, Old_String + before_length + find_length, after_length);
    memcpy(New_String, Before_String, before_length);
    memcpy(New_String + before_length, Replace_String, replace_length);
    memcpy(New_String + before_length + replace_length, After_String, after_length);
    return New_String;
}

int main(int argc, char* argv[])
{
    char * Find_String = "#74.125.224.72 asdf.com www.asdf.com";
    char * Replace_String = "74.125.224.72 asdf.com www.asdf.com";
    char * New_String;
    char * Output_Msg;
    int find_length = strlen(Find_String);
    FILE * ifp = fopen(FILENAME, "r+");
    int old_string_length = 0;
    while(getc(ifp) != EOF) old_string_length ++;
    char * Old_String = (char *) malloc(old_string_length);
    fseek(ifp, 0L, SEEK_SET);
    for (int i = 0; i < old_string_length; i++) Old_String[i] = getc(ifp);
    fclose(ifp);
    ifp = fopen(FILENAME, "w");

    int replace_point = finder(Old_String, Find_String);
    if(replace_point != -1)
    {
        New_String = replacer(replace_point, Old_String, Replace_String, find_length);
        Output_Msg = "\nSwitched to NEW VERSION (development version)\n\nIn your browser, while at www.asdf.com,\n\npress CTRL+F5 and/or F5 to refresh the page.\n\nYou may have to repeat F5 and/or CTRL+F5 several times.\n\n";       
    }
    else if(replace_point == -1)
    {
        Find_String = "74.125.224.72 asdf.com www.asdf.com";
        Replace_String = "#74.125.224.72 asdf.com www.asdf.com";
        find_length = strlen(Find_String);
        replace_point = finder(Old_String, Find_String);
        New_String = replacer(replace_point, Old_String, Replace_String, find_length);
        Output_Msg = "\nSwitched to OLD VERSION (production version)\n\nIn your browser, while at www.asdf.com,\n\npress CTRL+F5 and/or F5 to refresh the page.\n\nYou may have to repeat F5 and/or CTRL+F5 several times.\n\n";
    }

    if (New_String == NULL)
    {
        printf("\nError: Replace function returned NULL. Exiting... \n");
        system("pause");
        return 0;
    }
    //printf("\nNew String: \n%s \n\n\n", New_String);
    fseek(ifp, 0L, SEEK_SET);
    int i = 0;
    while(New_String[i] != '\0')
    {
        putc(New_String[i], ifp);
        i ++;
    }
    fclose(ifp);
    printf(Output_Msg);
    system("pause");
    return 0;
}
0 голосов
/ 03 февраля 2012
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXLINE 100
int main(int argc, char* argv[])
{
    FILE *ifp, *ofp;

    ifp = fopen("C:/Users/Buttle/Desktop/test.txt","r");
    if (ifp == NULL) {
         printf("Dang it didn't work!\n");
    }
    else printf("Dang it did work!\n");

    char line[MAXLINE];

    int linnum = 1;
    if(fscanf(ifp,"%s",line) != NULL) {           
        printf("line number %d\n" , linnum++ );                    
        if (strcmp(line, "74.125.224.72")==0 ) {                         
            fputs("#74.125.224.72 asdf.com www.asdf.com",stdout);
            //fputs("#74.125.224.72 asdf.com www.asdf.com",ifp);
        } else if (strcmp(line, "#74.125.224.72")==0 ){
            fputs("74.125.224.72 asdf.com www.asdf.com",stdout);
           // fputs("#74.125.224.72 asdf.com www.asdf.com",ifp);
        } else fputs("We ain't found sh--.",stdout);
        //else fputs("We ain't found sh--.",ifp);

    }

    fclose(ifp);
    return 0;
}

думаю, это поможет

0 голосов
/ 03 февраля 2012

Если вы делаете это всегда для одного и того же файла, всегда для одной и той же строки, я бы попробовал другой подход:

Запишите соответствующую строку с начальным пробелом и найдите положение этого пробела в файле. Тогда просто обновите его ...

#define CONFIG_FILE "hosts"
#define FIXED_POSITION 605

    handle = fopen(CONFIG_FILE, "r+b");
    fseek(handle, FIXED_POSITION, SEEK_SET);
    fputc(DEVELOPMENT ? '#' : ' ', handle);
    fclose(handle);
0 голосов
/ 03 февраля 2012

Ваш поиск подстроки неверен! Условие if (line == "74.125.224.72") должно быть заменено чем-то вроде:

if ( (strncmp("74.125.224.72", line, strlen("74.125.224.72")) == 0 )
{

}
0 голосов
/ 03 февраля 2012
char line[MAXLINE];

представляет массив. line соответствует адресу памяти, с которого начинается массив.

Вы сравниваете line с "74.125.224.72", это неправильно. Строки нельзя сравнивать таким образом.

Вам нужно использовать что-то вроде этого:

if (strcmp(line, "74.125.224.72") == 0) ... // return 0 if are same

С справочной страницы:

int strcmp (const char * s1, const char * s2);

Функция strcmp () сравнивает две строки s1 и s2. Возвращает целое число меньше, равно или больше нуля, если s1 соответственно меньше чем, чтобы соответствовать, или быть больше, чем s2.

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