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;
}
复制代码内容到meld_string.c
当然文件名也可以为其他。
之后命令行执行 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.