文件I / O:两个文件指针

时间:2016-01-20 14:22:29

标签: c file io

我是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);

}

2 个答案:

答案 0 :(得分:2)

那里有很多不同的问题,你应该一次专注于一个问题,如果它们与你的不同,可以发出不同的问题。

我将回答有关switch语句的第二个问题。答案是如果你想在一个案例中使用多个值,你就不能这样做。然而,如果没有break语句,可以依赖于案例落后这一事实,那么你就可以做到这一点。

switch (c)
{
case 'ä':
case 'Ä':
    // Code for the ä or Ä case
    break;

...
}

使用tolowertoupper

switch (tolower(c))
{
case 'ä':
    // Code for the ä or Ä case
    break;

...
}

关于case 'ä'||'Ä'的错误的一点解释。

编译器将'ä' || 'Ä'视为布尔表达式,在C中,所有非零都被视为 true 。同样在C boolean true 被认为等于1,这意味着你的案例中的表达式等于1 || 1,这是真的,因此1 ,所以你的所有案例都是case 1

答案 1 :(得分:1)

您可以拥有任意数量的打开文件指针(受到进程可以拥有的最大打开文件数量的限制),但在大多数现代操作系统中,此数字可以达到数千个。但是你应该记得把它们全部关闭。

至于&#34;递增&#34;文件指针,请记住,尽管类型被称为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)。