用C语言将中文文本和英文文本合并为一段中文一段英文(翻译排版)


前言

网上下载的所谓中英对照文本往往都是中英分开的两个文本:
在这里插入图片描述
在这里插入图片描述
很鸡肋,所以在这里讲一下如何将其设置为一段中文一段英文。
在这里插入图片描述



一.首先要对网上下载的文件进行必要的修改

注意

下载的资源可能存在中文段数和英文段数不一致的情况,这会直接影响输出结果,所以还是建议大家将文章分为多个部分排版,然后整合。

1.将段与段之间的空行删除

先将全文赋值粘贴到Word文档中,全选文档,然后按Ctrl+H弹出替换框,输入如图所示的字符(一个^p表示一个换行符,它的意思就是将连续两个换行符替换为一个)
在这里插入图片描述
然后选择全部替换,多点击几次全部替换,以免有漏网之鱼。
替换完成后:
在这里插入图片描述
可以看到,段之间的空行消失了。

2.将每一段段首设置为两个空格(包括标题)

(1)将Word文档复制到文本文档中

在这里插入图片描述

(2)使用替换

文本编辑器的替换很简单很人性:
在这里插入图片描述
先复制每段前面的空格 ,然后全选,再点击替换,将复制的空格粘贴,输入替换内容为英文输入法下的两个空格(英文空格使用的是ANSIC码,会方便我们后面的操作)。将段首解决后解决标题,同样的复制粘贴加替换。
完成后:
在这里插入图片描述

3.将完成好的文本复制粘贴到编译器中(Dev c++)

如图:
在这里插入图片描述
这一步的目的是将Unicode编码转换为ANSIC编码(后面使用文件函数时会方便很多ANSIC)。
保存这串“代码”,以后的操作都是对这个保存的“代码”进行的。
英文文档也按上面的方法操作,最终得到两个拓展名为.cpp的文件,我将其分别命名为ch.cpp和en.cpp。

二.程序设计

1.基本思路

以英文文档为例:文章的每一段都以两个空格开始,所以可以存储每一段段首和段尾的位置(距离文章第一个字符的字节数),在输出时,按照每段从段首到段尾输出。

2.代码实现

(1)数据存储

将每段段首和段尾的位置存储在结构体中:

typedef struct passe{
    
    
	long start;
	long end;
	struct passe *next;
}PassE;
typedef struct passc{
    
    
	long start;
	long end;
	struct passc *next;
}PassC;

(2)使用链表存储所有段落的开始和结束位置

以英文为例:

for(i=0;;i++)
	{
    
    
		fseek(fp_e,i,SEEK_SET);
		ch1=getc(fp_e);
		ch2=getc(fp_e);
		ch3=getc(fp_e);
		if(ch1==EOF||ch2==EOF||ch3==EOF)
		{
    
    
			last_e=(PassE*)malloc(sizeof(PassE));
			current_e->next =last_e;
			last_e->next=NULL;
			last_e->start =current_e->end;
			last_e->end =ftell(fp_e);
			break;
		}
		if(ch1==' '&&ch2==' '&&ch3!=' '&&i!=0)
		{
    
    
			end=i-1;
			current_e=(PassE*)malloc(sizeof(PassE));
			if(head_e==NULL)
			{
    
    
				head_e=current_e;
				head_e->start=0;
			}
			else
			{
    
    
				previous_e->next=current_e;
				current_e->start =previous_e->end ;
			}
			previous_e=current_e;
			current_e->end =end;
			current_e->next =NULL;
		}
	}
	

(3)输出文档

由于可能存在中文段数和英文段数不一致的情况,故在输出时需要判断中文和英文是否已经输出完毕,加入其中一个已经输出完毕,就结束关于它的操作(current_c->next=NULL,出现current_c=current_c->next,并且试图访问其中的数据的行为时,程序会异常退出)

	while(true)
		{
    
    
			if(argu_e)
			{
    
    
				for(i=current_e->start ;i<=current_e->end ;i++)
				{
    
    
					fseek(fp_e,i,SEEK_SET);
					ch=getc(fp_e);
					fprintf(fp_immi,"%c",ch);
				}
			}
			if(argu_c)
			{
    
    
				for(i=current_c->start ;i<=current_c->end;i++)
				{
    
    
					fseek(fp_c,i,SEEK_SET);
					ch=getc(fp_c);
					fprintf(fp_immi,"%c",ch);	
				} 
			}
			if(current_c->next!=NULL)//此时current_c已经输出过了 
				current_c=current_c->next ;
			else
			{
    
    
					argu_c=0;
			}
			if(current_e->next!=NULL)
				current_e=current_e->next ;
			else
			{
    
    
				
					argu_e=0;
			}
			
			if(argu_c==0&&argu_e==0)
				break;
		}
	

3.完整代码

#include<stdio.h> 
#include<stdlib.h>
typedef struct passe{
    
    
	long start;
	long end;
	struct passe *next;
}PassE;
typedef struct passc{
    
    
	long start;
	long end;
	struct passc *next;
}PassC;
int main(void)
{
    
    
	PassE *head_e=NULL,*current_e,*previous_e,*last_e;
	PassC *head_c=NULL,*current_c,*previous_c,*last_c;
	FILE *fp_e,*fp_c,*fp_immi;
	fp_e=fopen("en.cpp","r+");
	fp_c=fopen("ch.cpp","r+");
	fp_immi=fopen("immi.txt","r+");
	//获取英文字符 
	char ch1,ch2,ch3;
	long end,i;
	for(i=0;;i++)
	{
    
    
		fseek(fp_e,i,SEEK_SET);
		ch1=getc(fp_e);
		ch2=getc(fp_e);
		ch3=getc(fp_e);
		if(ch1==EOF||ch2==EOF||ch3==EOF)
		{
    
    
			last_e=(PassE*)malloc(sizeof(PassE));
			current_e->next =last_e;
			last_e->next=NULL;
			last_e->start =current_e->end;
			last_e->end =ftell(fp_e);
			break;
		}
		if(ch1==' '&&ch2==' '&&ch3!=' '&&i!=0)
		{
    
    
			end=i-1;
			current_e=(PassE*)malloc(sizeof(PassE));
			if(head_e==NULL)
			{
    
    
				head_e=current_e;
				head_e->start=0;
			}
			else
			{
    
    
				previous_e->next=current_e;
				current_e->start =previous_e->end ;
			}
			previous_e=current_e;
			current_e->end =end;
			current_e->next =NULL;
		}
	}
	
	for(i=0;;i++)
	{
    
    
		fseek(fp_c,i,SEEK_SET);
		ch1=getc(fp_c);
		ch2=getc(fp_c);
		ch3=getc(fp_c);
		if(ch1==EOF||ch2==EOF||ch3==EOF)
		{
    
    
			last_c=(PassC*)malloc(sizeof(PassC));
			current_c->next =last_c;
			last_c->next=NULL;
			last_c->start =current_c->end;
			last_c->end =ftell(fp_c);
			break;
		}
		if(ch1==' '&&ch2==' '&&ch3!=' '&&i!=0)
		{
    
    
			end=i-1;
			current_c=(PassC*)malloc(sizeof(PassC));
			if(head_c==NULL)
			{
    
    
				head_c=current_c;
				head_c->start=0;
			}
			else
			{
    
    
				previous_c->next=current_c;
				current_c->start =previous_c->end ;
			}
			previous_c=current_c;
			current_c->end =end;
			current_c->next =NULL;
		}
	}
	
		char ch;
		current_e=head_e;
		current_c=head_c;
		int argu_c=1,argu_e=1;
		while(true)
		{
    
    
			if(argu_e)
			{
    
    
				for(i=current_e->start ;i<=current_e->end ;i++)
				{
    
    
					fseek(fp_e,i,SEEK_SET);
					ch=getc(fp_e);
					fprintf(fp_immi,"%c",ch);
				}
			}
			if(argu_c)
			{
    
    
				for(i=current_c->start ;i<=current_c->end;i++)
				{
    
    
					fseek(fp_c,i,SEEK_SET);
					ch=getc(fp_c);
					fprintf(fp_immi,"%c",ch);	
				} 
			}
			if(current_c->next!=NULL)//此时current_c已经输出过了 
				current_c=current_c->next ;
			else
			{
    
    
					argu_c=0;
			}
			if(current_e->next!=NULL)
				current_e=current_e->next ;
			else
			{
    
    
				
					argu_e=0;
			}
			
			if(argu_c==0&&argu_e==0)
				break;
		}
	
	
	
}

4.效果

前一部分:
在这里插入图片描述
结尾:
在这里插入图片描述
在这里插入图片描述
可以看到出现了对不上号的情况,所以在运行代码前尽量确保中英文每一个段落可以对应的上(对文档的每一章单独整理,处理好格式,它的工作量不大)。

猜你喜欢

转载自blog.csdn.net/qq_33903332/article/details/115001417