android的同学们一定都晓得,每个工程都有多种语言字符串。
当我们需要检测翻译是否完整的时候,一个个字符串对比效率太低,为此给出小工具源码如下:
meld_string.c
#include<stdio.h> #include<string.h> #define LINE_BUFFER_SIZE 300 #define NAME_BUFFER_SIZE 100 void get_string_name(char* line, char* name); int check_args(int argc, char** argv, char* ret); int compared_file_with_string(FILE* file, char* string_name); const char* string_line_head = "<string name="; const char* null = 0l; int main(int argc, char** argv){ char* base_filename = NULL; char* compared_filename = NULL; char* result_filename = NULL; FILE *base_file; FILE *compared_file; FILE *result_file; char buffer[LINE_BUFFER_SIZE]; char name[NAME_BUFFER_SIZE]; int result = 0; //命令行输入参数检测 if(argc <= 1){ printf("\nPlease input files' name and retry!\n\n"); return 0; } if(argc == 3){ result_filename = "result"; } else if(argc == 4){ result_filename = argv[3]; } else{ printf("\nPlease input args as ./exc base_file_name compared_file_name [result_file_name] and retry!\n\n"); return 0; } base_filename = argv[1]; compared_filename = argv[2]; //printf("base filename is: %s\n", base_filename); if((base_file = fopen(base_filename, "r")) == NULL){ printf("open %s error!!\n", base_filename); return 0; } if((compared_file = fopen(compared_filename, "r")) == NULL){ printf("open %s error!!\n", compared_filename); return 0; } if((result_file = fopen(result_filename, "w+")) == NULL){ printf("open %s error!!\n", result_filename); return 0; } while(!feof(base_file)){ buffer[0] = '\0'; fgets(buffer, sizeof(buffer), base_file); //printf("read line: %s", buffer); if(0 == line_with_string_line_head(buffer)){ get_string_name(buffer, name); //printf("---------base file name = %s\n", name); result = compared_file_with_string(compared_file, name); if(result == 0){ //对比文件中也包含这个字符串 } else{ //对比文件中不包含这个字符串 // printf("%s\n", buffer); fputs(buffer, result_file); } rewind(compared_file); } } fclose(base_file); fclose(compared_file); fclose(result_file); printf("\nCompleted and printed to file named \"%s\" !!!\n\n", result_filename); return 0; } /** * 命令行输入参数检测 * 返回0:参数合法 * 返回其他:不合法 **/ int check_args(int argc, char** argv, char *result){ //printf("meld_string, the number of arguments == %d\n", argc); return 0; } /** * 获得字符串的名字 **/ void get_string_name(char* line, char* name){ char* h = line; char *start = NULL, *end = NULL; int length = 0; while(*(h) != '\0'){ if(*h == '\"'){ if(start == NULL){ start = h + 1; } else if(end == NULL){ end = h - 1; break; } } h++; } if(start != NULL && end != NULL){ length = (int)(end - start) + 1; strncpy(name, start, length); name[length] = '\0'; //very importent } else{ return; } } /** * 判断当前行是否含有"<string name=" * 如果含有则返回0 **/ int line_with_string_line_head(const char* line){ const char* start = line; int ret = -1; while(*(start) != '\0'){ if(*start == '<'){ ret = strncmp(start, string_line_head, 12); return ret; } start++; } return ret; } /** * 判断要比较的文件是否有此字符串名字 * 返回 0:有此name * 返回 其他:没有此name **/ int compared_file_with_string(FILE* file, char* string_name){ char buffer[LINE_BUFFER_SIZE]; char name[NAME_BUFFER_SIZE]; int ret = -1; while(!feof(file)){ buffer[0] = '\0'; fgets(buffer, sizeof(buffer), file); //printf("read line: %s", buffer); if(0 == line_with_string_line_head(buffer)){ get_string_name(buffer, name); // printf("compared file name = %s\n", name); ret = strcmp(string_name, name); // printf("compare ret = %d\n", ret); if(ret == 0) return ret; } } return ret; }
当然文件名也可以为其他。
之后命令行执行 gcc meld_string.c
会生成a.out可执行文件
命令行执行a.out base_file_name compared_file_name result_file_name
或者a.out base_file_name compared_file_name
就会在指定路径下生成对应的对比结果文件。
注释:
其中,base_file_name: 我们认为完整的字符串文件(android工程里的string.xml)
compared_file_name:跟base_file_name相比的文件(也是android工程里的string.xml)
result_file_name:指定生成比较结果(即base_file_name中含有,但是compared_file_name中不含有的字符串们)的文件名
在不指定的情况下,默认文件名为result.