使用不同的文件或不同的文件操作格式,为何也会使结果或是正确,或是乱码?
  • 板块学术版
  • 楼主Herman526
  • 当前回复9
  • 已保存回复9
  • 发布时间2023/5/27 13:52
  • 上次更新2023/10/23 14:37:12
查看原帖
使用不同的文件或不同的文件操作格式,为何也会使结果或是正确,或是乱码?
786834
Herman526楼主2023/5/27 13:52

最近,我写了一段在 2∼n2\sim n 范围内分解质因数、打印质数的代码。

#include<bits/stdc++.h>
using std::vector;
void w(int x,char c){
	char s[10]="",l=-1;
	while(x)s[++l]=x%10,x/=10;
	while(putchar(s[l]+48),l--);
	putchar(c);
}//快写
int main(){
	char c;
	while(c=getchar(),c<48||c>57);
	int n=c-48;
	while(c=getchar(),c>47&&c<58)n=n*10+c-48;//快读
	int*p=new int[n+1]{},l=0;vector<int>q;
	freopen("times.txt","wb",stdout);//由于输出量较大,故采用文件输出
	for(int i=2;i<=n;i++){
		if(!p[i])q.push_back(p[i]=i),l++;
		w(i,61);
		for(int j=i;;j/=p[j])if(j^p[j])w(p[j],42);
		else{w(p[j],10);break;}
		for(int j=0;j<l&&q[j]*i<=n;j++)if(!(i%(p[q[j]*i]=q[j])))break;
	}//欧拉筛法
	delete[]p;
	freopen("primes.txt","wb",stdout);
	for(int i=0;i<l;i++)w(q[i],10);
}

在 Windows 7,10 电脑上编好代码后,我输入了 100100,程序也给出了正确结果。但是,当我输入了一个 10610^6 以后,虽然 times.txt 的输出正确,但 primes.txt 却是大量乱码(此为图片)。我又更换了输入,看一下会不会出现这样的问题。最终,我发现,当 n⩽1408n\leqslant1408 时,primes.txt 是正确的,但只要 n⩾1409n\geqslant1409(14091409 是 14001400 后的第 11 个质数,也是从小到大第 223223 个质数),primes.txt 就是乱码。


看到如此令人惊讶的结果,我想:这是不是和文件操作格式有关呢?我将打印到 times.txt 中的代码注释掉,又更改了格式,果然不出所料,只要文件格式中含有字符 b(wb,ab,rb+,wb+,ab+),就会出现雷同的乱码,否则(w,a,r+,w+,a+)就是正确。

在上述结果中,只有输入含字符 b 的文件操作格式,程序才会出错。但是,在只打印 1 与 \n 的情况下,不管是用什么追加操作,primes.txt 都有字符 റ,但其它操作却能让它安然无恙;而与此同时,times.txt 却一点问题都没有。这样的结果让我十分奇怪:为什么在不同的情况下,安全性高的文件操作格式会如此不同?一定得打印到第 223223 个质数,才会出现乱码吗?难道电脑就对 primes.txt 那么“有仇”(总想让它全是乱码),而对 times.txt 那么“友好”?

2023/5/27 13:52
加载中...