首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C中的FileParsing

C中的FileParsing
EN

Code Review用户
提问于 2020-09-06 06:12:46
回答 2查看 446关注 0票数 4

因此,我有一个充满了老洋葱链接的文本文件,它令人难以置信的混乱:

代码语言:javascript
复制
1   Dark web Link– Deep Web Links – Hidden Wiki     http://dwlonion3o3pjqsl.onion/  online
2   Darkode Reborn  http://darkodevasbv5yof.onion   online
3   Arm’s Factory   http://gunsfact2f6oz7cw.onion/  online
4   Dark Web Hackers Zone   http://darkzonebry27nxa.onion/  online
5   Raptor (Tor Chat Service)   http://raptortiabg7uyez.onion   online

*每一行看起来都是:(int)\t(name) (url) (status)

因为我的C代码往往很糟糕,所以我想改进它。我编写了一个简单的文件解析器,它试图只考虑url和状态,并且想知道是否有任何方法来优化我的代码/改进排序函数,因为这是我觉得最弱的地方:

main.c

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include "sorter.h"

#define onionLinksFile "onionlinks.txt"
#define output "sorted\\output.txt" //folder for output

int main() {

    FILE *file = fopen(onionLinksFile, "r");
    FILE *nFile = fopen(output, "w+");
    char line[256]; //allocate up to 256 chars for each line
    if (file == NULL){
        printf("> An error occured while attempting to open our file...");
        return 1;
    }

    while (fgets(line, sizeof(line), file)) { //get each newline
        fprintf(nFile, sort(line)); //write our sorted data to our text file
        //printf(line);
    }
    
    fclose(file);
    fclose(nFile);

    return 0;
}

sorter.h

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>

#define delimter "\t" //our delimters
#define mDelimter "//"

char *sort(char line[256]) {
    int objCount = 0;
    int mObjCount = 0;
    
    char *token = strtok(line, delimter);
    while (token != NULL){ //attempt to split our string by tabs
        objCount++;

        if (objCount > 1){ //ignore the first number, don't care about that
            char *nToken = strtok(token, mDelimter);

            while (nToken != NULL){ //split the string again this time take everything past the //
                mObjCount++;
                if (mObjCount > 1){
                    return nToken;
                }
                nToken = strtok(NULL, "");
            }

        }
        token = strtok(NULL, "");
    }
}

下面是输出的样子:

代码语言:javascript
复制
/dwlonion3o3pjqsl.onion/    online
/darkodevasbv5yof.onion     online
/gunsfact2f6oz7cw.onion/    online
/darkzonebry27nxa.onion/    online
/raptortiabg7uyez.onion     online
/gurochanocizhuhg.onion/    offline
/6a3nny6zpg23dj7g.onion/    offline
EN

回答 2

Code Review用户

回答已采纳

发布于 2020-09-06 12:20:57

一般观测

如果您是唯一的用户,这个程序是很棒的,但是如果它是供其他人使用的,这里有一些建议:

  1. 允许用户以不同的方式提供输入和输出文件,而不是硬编码输入和输出文件的名称。
  2. 如果输入错误,请为用户提供指导。
  3. 改进错误处理。

如果程序是从命令行执行的,至少有3种方法可以由这样的程序处理输入和输出:

  1. 文件重定向
  2. 命令行参数
  3. 程序提示用户输入和输出文件名。

应该注意的是,一个程序可以使用所有三种方法来达到最灵活的效果。

如果用户使用的是文件重定向,而不是stdin上输入的文件重定向,并且输出是在stdout上输出的,那么错误应该转到stderr。在这种情况下,代码

代码语言:javascript
复制
    FILE* file = stdin;
    FILE* nFile = stdout;

将是适当的,其余的代码仍将像现在一样工作。

使用命令行参数,程序必须使用int main(int argc, char **argv)来获取文件名。

当代码检查输入文件是否可以打开以供输入时,它并不检查输出文件是否可以打开以便输出,并且可能导致错误。

在需要时声明变量(

)

变量line是在main()的顶部定义的,如果line在驱动程序的while()循环之前声明,将使代码更易于理解和维护。这也将使我们更容易看到while loop本身可能是一个函数。

头文件

最佳实践

在C中,#include预处理器指令实际上将包含的文件与包含指令一起复制到文件中,为了防止包含在所包含文件中的代码被包含,需要有某种机制来防止代码被包含两次。有两种机制,使用包含保护或使用#pragma once。我更喜欢使用#pragma once有两个原因,一个是它更传统(我很老了),第二个原因是虽然许多编译器广泛支持它,但它目前既不是C标准的一部分,也不是C++标准的一部分。

包括警卫:

代码语言:javascript
复制
#ifndef FILE_NAME_H_
#define FILE_NAME_H_

... code ...

#endif  // !FILE_NAME_H_

头文件通常用于提供来自另一个C源文件的API或函数原型,头文件包含可执行代码是非常罕见的,因为如果头文件由多个源文件包含,则其中的函数存在于程序中的多个位置,程序不会链接。

启用所有编译器警告

编译代码时,使用-wall开关启用所有警告时,sort()函数当前存在一些逻辑问题,从而产生以下警告消息:

'sort': not all control paths return a value。此警告消息表示函数可以在不提供值的情况下返回,并且可以指示代码中存在严重问题。

标准符号常数

因为程序包括stdlib.h,所以有两个符号常量可以使main()更易读,EXIT_SUCCESSEXIT_FAILURE。这些符号常量可以代替return 0;return 1;main()中。

票数 5
EN

Code Review用户

发布于 2020-09-06 18:39:59

首先对'//‘进行tokenise,然后再对'\t’上的第二个数组元素进行tokenise,会更有效。这将避免某些字符串复制。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/248985

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档