对于一些初学C语言的小萌新们来说,在中文字符串对TXT文件进行输入、储存、读取这一系列的操作上可能会存在这么一些问题: 1.进行输入、储存后,打开在TXT文件一看,显示的是乱码; 2.在TXT文件中显示的是正确的中文字符,但是一读取,用printf一输出,显示的是乱码,或者是正确的中文字符夹杂着一堆“烫烫烫烫烫…”; 3.对输入中文字符时夹杂着的各种其他字符不知道怎么处理,诸如“安装a的”、“年成都2的”…新手可能会对怎么将他们中的其他字符剔除而只保留中文字符输入存在疑惑; 4.怎么让它在读取中文字符时自动读取的中文字数就是我上次输入的。
这些问题我在下面会进行相应的解答,并在最后放出可运行的代码示例。
首先,第一个问题,这个倒问题不大,出现这种情况一般来说可能有两种原 因:1.你的代码有问题,大问题上我现在也不知道你到底错在了哪里,这只能是你自己对比一下看看咯;2.你的TXT格式文件在创建时默认编码为UTF-8,这导致在读取文件时编码格式不对应而造成读取中文时出现乱码,这个你得把它改为ASNI编码格式,这样就解决了。 下图第一个就是对的,能正常显示写入的中文: 错误案例图:
第二个问题,就是你用来读取保存中文字符串的字符数组只声明创建而不进行初始化赋值导致的,你只要对那个字符数组进行初始化赋值应该就没问题了。如:原本是“ char s[1000]; ” ,改成“ char s[1000]=“s”; ”就行了。
第三个问题,就要结合我们的ASCII码,我们常见的各种字符,包括数字、英文字母、《》、<、= 等等,大多数都可以说是将键盘上的所有字符囊括其中了,它们的每个符号都有专属于自己的值,从0到127,都是非中文字符,我们剔除掉就好,中文字符的值小于0,因此我们可以用循环和判断将我们需要的逐个筛选出来,问题也就解决了。
第四个问题,这个涉及到将int值、string值、const char *值之间的转化,感兴趣的看下面的代码示例就行了,这里也没什么好说的。
这个是C语言版本的:
#include<string>
#include<stdio.h>
#include<stdlib.h>
//#include<string.h>
void china_name_writer()
{
char china_name_writer[3000];
int china_name_writer_long_number;
while (1)
{
while (1)
{
int c;
printf("注意:一个汉字占两个字符宽度位置,例如:char c[2]只能保留一个汉字,超出将报错");
printf("\n");
printf("请输入您想输入汉字的字数:");
scanf_s("%d", &c);
getchar();
if (c >= 3000)
{
printf("您想要输入的汉字过多,已超出最大字数限度,请重新输入");
printf("\n");
}
if (c <= 0)
{
printf("您想要输入的汉字过少,已超出最小字数限度,请重新输入");
printf("\n");
}
if (c > 0 && c <= 3000)
{
china_name_writer_long_number = c;
break;
}
}
china_name_writer_long_number = china_name_writer_long_number * 2;
if (china_name_writer_long_number > 0 && china_name_writer_long_number <= 3000)
{
break;
}
if (china_name_writer_long_number >= 3000)
{
printf("您想要输入的汉字过多,已超出最大字数限度,请重新输入,可分批输入");
printf("\n");
}
printf("\n");
}
printf("\n");
printf("请输入中文:");
gets_s(china_name_writer);
printf("\n");
printf("%s", china_name_writer);
FILE *fp;
fopen_s(&fp, "hanzi.txt", "wt+");
fwrite(china_name_writer, china_name_writer_long_number * sizeof(char), 1, fp);
fclose(fp);
///
//写入、保存数字数据
std::string num_str = std::to_string(china_name_writer_long_number / 2);
const char *num_str_char = num_str.c_str();
FILE *fp_shuzi;
fopen_s(&fp_shuzi, "shuzi.txt", "wt+");
int name_number_long = strlen(num_str_char);
switch (name_number_long)
{
case 1:
fwrite(num_str_char, sizeof(char), 1, fp_shuzi);
fclose(fp_shuzi);
break;
case 2:
fwrite(num_str_char, 2 * sizeof(char), 1, fp_shuzi);
fclose(fp_shuzi);
break;
case 3:
fwrite(num_str_char, 3 * sizeof(char), 1, fp_shuzi);
fclose(fp_shuzi);
break;
case 4:
fwrite(num_str_char, 4 * sizeof(char), 1, fp_shuzi);
fclose(fp_shuzi);
break;
case 5:
fwrite(num_str_char, 5 * sizeof(char), 1, fp_shuzi);
fclose(fp_shuzi);
break;
default:
break;
}
}
void china_name_read(std::string input_output)
{
std::string num_read_str;
//读取数字
//在这里对这个数组变量进行初始化赋值是必须的,你付给它们对应的什么值都行,但一定要赋值
//否则你读取TXT文件后用printf显示的时候会发现:它们存在乱码!
char num_read_char[1000] = "s";
FILE *fp_num_read;
fopen_s(&fp_num_read, "shuzi.txt", "rt+");
fread(num_read_char, 1000 * sizeof(char), 1, fp_num_read);
fclose(fp_num_read);
int num_read = 0;
for (int r = 0; r < 1000 && num_read_char[r] != '\0'; r++)
{
if (num_read_char[r] == '\0' || (int)num_read_char[r]<48 || (int)num_read_char[r]>57)
{
break;
}
//&& (int)num_read_char[r] >= 0
if (num_read_char[r] != '\0' && (int)num_read_char[r] >= 48 && (int)num_read_char[r] <= 57)
{
int num_single = (int)num_read_char[r] - 48;
if (num_read_char[r + 1] != '\0' && (int)num_read_char[r + 1] >= 48 && (int)num_read_char[r + 1] <= 57)
{
num_single = num_single * 10;
num_read = num_read * 10;
num_read += num_single;
}
if (num_read_char[r + 1] == '\0' || (int)num_read_char[r + 1]<48 || (int)num_read_char[r + 1]>57)
{
num_read += num_single;
break;
}
}
}
//num_read_str = num_read_char;
printf("%d", num_read);
printf("\n");
/
//读取汉字
// 在这里对这个数组变量进行初始化赋值是必须的,你付给它对应的什么值都行,但一定要赋值
//否则你读取TXT文件后用printf显示的时候会发现:它存在乱码!
char s[1000] = "s", ch;
FILE *fp_r;
int i = 0;
fopen_s(&fp_r, "hanzi.txt", "rt+");
//
//(
//按字符方式读取文件,每读一个字符判断一下是否为汉字编码(<0),若是则存入字符数组,不是则跳过读取下一个字符,直到文件结束。
while ((ch = fgetc(fp_r)) != EOF && i<(num_read * 2))
{
if ((int)ch >= 0 && (int)ch <= 127)
{
continue;
}
if (ch < 0)
{
s[i++] = ch;
}
}
fclose(fp_r);
printf("s:%s", s);
printf("\n");
//不能直接将中文字符数组赋给string,不然string变量得到的也只是乱码
//input_output = s;
//printf("input_output:%s", input_output);
//printf("\n");
}
int main()
{
china_name_writer();
///
printf("\n");
int choice;
printf("是否读取(是则输入1):");
printf("\n");
scanf_s("%d", &choice);
/
std::string a;
if (choice == 1)
{
china_name_read(a);
}
system("pause");
return 0;
}
这个是c++版本的:
#include<iostream>
#include<string>
#include<stdio.h>
#include<stdlib.h>
//#include<string.h>
void china_name_writer()
{
std::string hanzi;
char china_name_writer[3000];
int china_name_writer_long_number;
while (1)
{
while (1)
{
int c;
std::cout << "注意:一个汉字占两个字符宽度位置,例如:char c[2]只能保留一个汉字,超出将报错";
std::cout << "\n";
std::cout << "请输入您想输入汉字的字数:";
std::cin >> c;
//
// 判断输入是否有效
while (std::cin.fail())
{
std::cin.clear();
std::cin.ignore(1000, '\n');
std::cout << "您只能输入数字.";
std::cout << "请输入选项(数字):";
std::cin >> c;
std::cout << std::endl;
}
//
if (c >= 3000)
{
std::cout << "您想要输入的汉字过多,已超出最大字数限度,请重新输入";
std::cout << "\n";
}
if (c <= 0)
{
std::cout << "您想要输入的汉字过少,已超出最小字数限度,请重新输入";
std::cout << "\n";
}
if (c > 0 && c <= 3000)
{
china_name_writer_long_number = c;
break;
}
}
china_name_writer_long_number = china_name_writer_long_number * 2;
if (china_name_writer_long_number > 0 && china_name_writer_long_number <= 3000)
{
break;
}
if (china_name_writer_long_number >= 3000)
{
std::cout << "您想要输入的汉字过多,已超出最大字数限度,请重新输入,可分批输入";
std::cout << "\n";
}
std::cout << "\n";
}
std::cout << "\n";
std::cout << "请输入中文:";
std::cin >> china_name_writer;
//std::cin >> hanzi;
//gets_s(c, 30);
std::cout << "\n";
std::cout << china_name_writer;
std::string hanzi_beifen;
FILE *fp;
fopen_s(&fp, "hanzi.txt", "wt+");
fwrite(china_name_writer, china_name_writer_long_number * sizeof(char), 1, fp);
fclose(fp);
///
//写入、保存数字数据
std::string num_str = std::to_string(china_name_writer_long_number / 2);
const char *num_str_char = num_str.c_str();
FILE *fp_shuzi;
fopen_s(&fp_shuzi, "shuzi.txt", "wt+");
int name_number_long = strlen(num_str_char);
switch (name_number_long)
{
case 1:
fwrite(num_str_char, sizeof(char), 1, fp_shuzi);
fclose(fp_shuzi);
break;
case 2:
fwrite(num_str_char, 2 * sizeof(char), 1, fp_shuzi);
fclose(fp_shuzi);
break;
case 3:
fwrite(num_str_char, 3 * sizeof(char), 1, fp_shuzi);
fclose(fp_shuzi);
break;
case 4:
fwrite(num_str_char, 4 * sizeof(char), 1, fp_shuzi);
fclose(fp_shuzi);
break;
case 5:
fwrite(num_str_char, 5 * sizeof(char), 1, fp_shuzi);
fclose(fp_shuzi);
break;
default:
break;
}
}
void china_name_read(std::string input_output)
{
std::string num_read_str;
//读取数字
//在这里对这个数组变量进行初始化赋值是必须的,你付给它们对应的什么值都行,但一定要赋值
//否则你读取TXT文件后用printf显示的时候会发现:它们存在乱码!
char num_read_char[1000]="s";
FILE *fp_num_read;
fopen_s(&fp_num_read, "shuzi.txt", "rt+");
//for(int n=0;n<1000;n++)
fread(num_read_char, 1000 * sizeof(char), 1, fp_num_read);
//int *n_i;
//fread(n_i, sizeof(int), 1, fp_num_read);
//std::cout << "int* n_i:" << &n_i;
//std::cout << "\n";
fclose(fp_num_read);
int num_read = 0;
for (int r = 0; r < 1000 && num_read_char[r] != '\0'; r++)
{
if (num_read_char[r] == '\0' || (int)num_read_char[r]<48 || (int)num_read_char[r]>57)
{
break;
}
//&& (int)num_read_char[r] >= 0
if (num_read_char[r] != '\0' && (int)num_read_char[r] >= 48 && (int)num_read_char[r] <= 57)
{
std::cout << "第" << r << "位字符:" << num_read_char[r];
std::cout << "\n";
int num_single = (int)num_read_char[r] - 48;
std::cout << "第" << r << "位数字:" << num_single;
std::cout << "\n";
if (num_read_char[r + 1] != '\0' && (int)num_read_char[r + 1] >= 48 && (int)num_read_char[r + 1] <= 57)
{
num_single = num_single * 10;
num_read = num_read * 10;
num_read += num_single;
}
if (num_read_char[r + 1] == '\0' || (int)num_read_char[r + 1]<48 || (int)num_read_char[r + 1]>57)
{
num_read += num_single;
break;
}
}
}
//num_read_str = num_read_char;
std::cout << num_read;
std::cout << "\n";
/
//读取汉字
// 在这里对这个数组变量进行初始化赋值是必须的,你付给它对应的什么值都行,但一定要赋值
//否则你读取TXT文件后用printf显示的时候会发现:它存在乱码!
char s[1000]="s", ch;
FILE *fp_r;
int i = 0;
fopen_s(&fp_r, "hanzi.txt", "rt+");
//
//(
//按字符方式读取文件,每读一个字符判断一下是否为汉字编码(<0),若是则存入字符数组,不是则跳过读取下一个字符,直到文件结束。
while ((ch = fgetc(fp_r)) != EOF && i<(num_read * 2))
{
if ((int)ch >= 0 && (int)ch <= 127)
{
continue;
}
if (ch < 0)
{
s[i++] = ch;
}
}
fclose(fp_r);
//std::cout << "s:" << s;
//std::cout << "\n";
input_output = s;
std::cout << "input_output:" << input_output;
std::cout << "\n";
}
int main()
{
china_name_writer();
///
std::cout << "\n";
int choice;
std::cout << "是否读取(是则输入1):";
std::cin >> choice;
/
std::string a;
if (choice == 1)
{
china_name_read(a);
}
system("pause");
return 0;
}
|