之前看到了这样一道题目:手动创建两个文本文件 text1.txt,text2.txt,要求编程创建 text3.txt,实现 text1.txt 和 text2.txt 文件中除去首行和末尾对应的数据相加。
题目中的首行和末尾分别是单词 begin 和 end, 但它给的数据是这样的:text1:10 11 12 ,20 21 22 , 30 31 32 ;text2:15 16 17 , 25 26 27, 35 36 37。
这样的数据就让题目变得很简单,只需要用到 fgetc() 函数判断读到的字符是否为数字字符,是就将它们相加减去 '0' 再写入text3 就好了,可以不用考虑进位。
但出于细(mei)心(shi)钻(zhao)研(shi)的理念,笔者还是想将题目改一下,让它的数字经过相加后可以进位,比如改成19加上95等。
初步的想法是,利用一个数组,当我用fgetc() 函数读到一个数字字符时,我就将它存到字符数组中,直到读到一个不是数字的字符时,我在数组的末尾加上 ' \0 ',
然后利用字符串转数字函数 atoi() 转化2个字符串再将其相加得到我需要写进text3中的数字,当然它还只是个数字。这时候,我们可以自己动手写一个 itoa 的函数嘛,
将数字求余得到的结果转化成字符放在一个数组中,再将数组元素一一写进text3中就实现了两文件之间数字的相加,当然,最后不要忘了之前读到的不是数字的字符,
它还在等着你用fputc() 函数将它写入text3中呢。
以上就是大体的想法,实现起来还需要注意一些小的细节,比如将数组 a [ i ] 中的数读出来后,要将 i 重新置为0啊,还有当读到非数字字符时,atoi() 还是能得到数字0啊,
以及otai() 函数该怎么写之类的,都是需要一些思考的。下面贴上该程序:
#include <stdio.h>
int itoa (int n, char ch[])
{
int i = 0;
if (n == 0)
return 0;
do
{
ch[i++] = n % 10 + '0';
}while ((n /= 10) > 0); // 注意循环条件 (n /= 10) > 0, 不能少了 '='
return i-1;
}
int main()
{
FILE *fp1 = fopen("text1.txt", "ab+");
if (fp1 == NULL)
{
perror ("fopen_text1");
return -1;
}
FILE *fp2 = fopen("text2.txt", "ab+");
if (fp2 == NULL)
{
perror ("fopen_text2");
return -1;
}
FILE *fp3 = fopen("text3.txt", "ab+");
if (fp3 == NULL)
{
perror ("fopen_text3");
return -1;
}
char str1[5];
char str2[5];
char ch[5] = "0";
int i = 0;
int j = 0;
while (1)
{
char c1 = fgetc(fp1);
char c2 = fgetc(fp2);
if (c1 == EOF || c2 == EOF)
break;
if ('0' <= c1 && '9' >= c1 && '0' <= c2 && '9' >= c2)
{
str1[i++] = c1;
str2[j++] = c2;
}
else
{
str1[i] = '\0';
str2[j] = '\0';
int num = atoi(str1) + atoi(str2);
int h = itoa (num, ch); // 返回值h用来区别非数字字符的写入
for (i = h; i >= 0; i--)
{
if (h == 0)
{
break; // 不是数字字符返回值为0,就不写入
}
else
{
fwrite (&ch[i], sizeof(char), 1, fp3);
}
}
fputc (c1, fp3);
i = 0; // 将i, j 重新置为 0,以便再往数组中写数字
j = 0;
}
}
fclose(fp1);
fclose(fp2);
fclose(fp3);
return 0;
}