我是FILE I / O Stream的新手,我想编写一个程序,将chars(从“texti.txt”读取)转换为“ä,Ä,ü,Ü,ö,Ö”到“ae” ,Ae,ue,Ue,oe,Oe“并将它们写在一个名为”texto.txt“的新文件中。
第一个问题: 是否可以像我一样同时拥有两个文件指针(每个文件)?
第二个问题: 我在switch语句中使用字符比较做错了什么? VS2015警告案例2和3已存在(参考案例1)
第三个问题
fpo
(输出文件的文件指针)是否通过写入char?
问题四: VS2015警告:
C4996'fopen':此函数或变量可能不安全。考虑使用fopen_s代替。要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS。有关详细信息,请参阅在线帮助。
我应该使用其他功能吗?
int main()
{
char c;
FILE *fpi;
FILE *fpo;
fpi = fopen("texti.txt","r");
fpo = fopen("texto.txt", "w");
if (fpi == NULL)
fprintf(stderr, "Fehler beim Lesen");
while (!feof(fpi))
{
c = fgetc(fpi);
switch (c)
{
case 'ä'||'Ä':
fputc('a', fpo);
fputc('e', fpo);
break;
case 'ö'||'Ö':
fputc('o', fpo);
fputc('e', fpo);
break;
case 'ü' || 'Ü':
fputc('u', fpo);
fputc('e', fpo);
break;
default:
fputc((c), fpo);
}
fpi++;
}
fclose(fpi);
fclose(fpo);
}
答案 0 :(得分:2)
那里有很多不同的问题,你应该一次专注于一个问题,如果它们与你的不同,可以发出不同的问题。
我将回答有关switch语句的第二个问题。答案是如果你想在一个案例中使用多个值,你就不能这样做。然而,如果没有break
语句,可以依赖于案例落后这一事实,那么你就可以做到这一点。
switch (c)
{
case 'ä':
case 'Ä':
// Code for the ä or Ä case
break;
...
}
switch (tolower(c))
{
case 'ä':
// Code for the ä or Ä case
break;
...
}
关于case 'ä'||'Ä'
的错误的一点解释。
编译器将'ä' || 'Ä'
视为布尔表达式,在C中,所有非零都被视为 true 。同样在C boolean true 被认为等于1
,这意味着你的案例中的表达式等于1 || 1
,这是真的,因此1
,所以你的所有案例都是case 1
。
答案 1 :(得分:1)
您可以拥有任意数量的打开文件指针(受到进程可以拥有的最大打开文件数量的限制),但在大多数现代操作系统中,此数字可以达到数千个。但是你应该记得把它们全部关闭。
至于"递增"文件指针,请记住,尽管类型被称为FILE *
,但它实际上并未指向文件的内容,它指向{{1}的内部管理结构用于处理文件。因此,像<stdio.h>
这样的东西不会更新内部文件位置指针(这是你想要做的);它只是让fpi ++
指向其他fpi
结构。虽然有合理的理由这样做(例如,指向FILE
数组的指针),但在文件内移动并不是这样做的。
如果您确实需要在文件中移动,那么有一个名为FILE *
的函数可以执行此操作。但是,读取或写入(即调用fseek()
,fread()
,fwrite()
,fgets()
,fprintf()
(及其等效的getc()
), fgetc()
(及其等效的putc()
),以及您可以想象的对fputc()
值表示的文件执行I / O的任何其他函数)已经更新了内部文件指针以指向数据之后该操作处理。换句话说,当您读取或写入字符时,内部文件指针将指向该字符之后。您不需要,也不应该尝试自己更新,因为它已经为您完成了。
由于编码,字符比较可能会失败 - 虽然有一种非常标准的方式来表示通常的ASCII字符(代码点32到126;基本字母,数字等),国际字符不具备这种奢侈。您需要找出文件使用的编码,并手动处理该编码;可能是通过使用原始字符数而不是字符表示法。如果你想研究它,还有广泛的角色功能可以帮助你。
编辑:我刚刚注意到FILE *
标签中的'C' || 'c'
符号。这简单地计算为1,因为case
标签中的任何常量表达式在编译时被解析(并且根本不允许非常量表达式)。您需要多个case
标签才能匹配多个值;你不能在那里使用表达式。
最后,VS警告是虚假的,因为case
是标准库调用。但请记住fopen()
相应的文件(在这种情况下为#include
)。