因此,我有一个充满了老洋葱链接的文本文件,它令人难以置信的混乱:
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和状态,并且想知道是否有任何方法来优化我的代码/改进排序函数,因为这是我觉得最弱的地方:
#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;
}#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, "");
}
}下面是输出的样子:
/dwlonion3o3pjqsl.onion/ online
/darkodevasbv5yof.onion online
/gunsfact2f6oz7cw.onion/ online
/darkzonebry27nxa.onion/ online
/raptortiabg7uyez.onion online
/gurochanocizhuhg.onion/ offline
/6a3nny6zpg23dj7g.onion/ offline发布于 2020-09-06 12:20:57
如果您是唯一的用户,这个程序是很棒的,但是如果它是供其他人使用的,这里有一些建议:
如果程序是从命令行执行的,至少有3种方法可以由这样的程序处理输入和输出:
应该注意的是,一个程序可以使用所有三种方法来达到最灵活的效果。
如果用户使用的是文件重定向,而不是stdin上输入的文件重定向,并且输出是在stdout上输出的,那么错误应该转到stderr。在这种情况下,代码
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++标准的一部分。
包括警卫:
#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_SUCCESS和EXIT_FAILURE。这些符号常量可以代替return 0;和return 1;在main()中。
发布于 2020-09-06 18:39:59
首先对'//‘进行tokenise,然后再对'\t’上的第二个数组元素进行tokenise,会更有效。这将避免某些字符串复制。
https://codereview.stackexchange.com/questions/248985
复制相似问题