尝试创建简单的C程序来编辑文本文件中的1行

时间:2012-02-03 11:00:11

标签: c file-io

我正在尝试创建一个只在主机文件中切换一行的C可执行文件。

e.g。改变这个:

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 个答案:

答案 0 :(得分:2)

首先,你需要两个文件(或者你必须实现缓冲区才能全部读取。所以:

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);
    }
}

您可能需要包含多个头文件,但我希望您能够将其谷歌搜索:)

答案 1 :(得分:0)

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。

答案 2 :(得分:0)

您的子字符串搜索错误!条件if (line == "74.125.224.72")必须替换为:

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

}

答案 3 :(得分:0)

如果你总是为同一个文件做同样的事情,我会尝试不同的方法:

使用前导空格编写有问题的行,并在文件中找到该空间的位置。然后只需更新它......

#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);

答案 4 :(得分:0)

#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;
}

我认为这会有所帮助

答案 5 :(得分:-1)

我的朋友帮我提出了一个解决方案,所以我会在这里发布。最奇怪的是我尝试了几个不同的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;
}