如何在文本文件中将小写字符替换为大写

时间:2017-09-17 19:25:27

标签: c

我将每个小写字符转换为大写字母,但它没有替换文件。我究竟做错了什么?

#include <stdio.h>

int main() {
    FILE *file;
    char ch;
    file = fopen("file.txt", "r+");
    if (file == NULL) {
        printf("Error");
        exit(1);
    } else {
        while ((ch = fgetc(file)) != EOF) {
            if (ch >= 96 && ch <= 123) {
                ch = ch - 32;
                putc(ch, file);
            }
        }
        fclose(file);
        return 0;
    }
}

4 个答案:

答案 0 :(得分:3)

您必须打开另一个要写的文件。

fileOut = fopen("fileOut.txt", "w");

ch必须是整数。

int ch;

检查这样的男人页面。

#man fgetc

putc(ch,fileOut); 

应该超出if阻止。

答案 1 :(得分:1)

问题在于,对于fopen/'+',从读取切换到写入需要对文件定位功能的中间调用,例如, fseek

  

7.21.5.3 fopen功能

     

(7)以更新模式打开文件时(&#39; +&#39;作为第二个或第三个   上面的模式参数值列表中的字符),输入和   可以在关联的流上执行输出。但是,输出   在没有干预呼叫的情况下,不得直接输入   fflush功能或文件定位功能(fseek,fsetpos,   或倒带),输入不得直接输出而不输出   除非输入,否则对文件定位功能进行干预调用   操作遇到文件结束。打开(或创建)文本文件   使用更新模式可以改为打开(或创建)某些二进制流   的实施方式。

所以你可能要编写像

这样的东西
fseek (fp , -1, SEEK_CUR);
putc(ch,file);
fseek (fp , 0, SEEK_CUR);

但请注意,在(可能)大文件中逐个替换字符效率相当低。首选的方法是读入一个文件,进行转换并写入另一个文件,最后 - 用另一个文件替换一个文件。如果无法实现,请至少尝试读入/转换/写回更大的块(不是逐字节)。

只是为了检查逐字节转换是否真的效率低下,我把它与一块一块一块的方法进行了比较。事实证明 - 至少在我的机器上 - 在这个测试中,chunk-by-chunk比逐字节快500倍。文件大小约为100k:

int main(void) {
    FILE *file;
    int ch;
    file = fopen("/Users/stephanl/Desktop/ImplantmedPic_Storeblok.jpg", "rb+");
    if (file == NULL) {
        printf("Error: cannot open file.txt\n");
        return 1;
    } else {
        clock_t t1 = clock();

        // The following variant takes about 900 ticks:
        unsigned char buffer[1000];
        unsigned long l;
        while (1) {
            unsigned long fpi = ftell(file);
            l=fread(buffer, 1, 1000, file);
            if (l==0)
                break;

            for (int i=0;i<l;i++) {
                buffer[i]=~buffer[i];
            }

            fseek(file, fpi, SEEK_SET);
            fwrite(buffer,1,l, file);
            fseek(file, 0L, SEEK_CUR);
        }


        // this variant takes about 500.000 ticks
        while ((ch = fgetc(file)) != EOF) {
                fseek(file, -1L, SEEK_CUR);
                putc(~ch, file);
                fseek(file, 0L, SEEK_CUR);
        }

        fclose(file);
        clock_t t2 = clock();
        printf ("difference: %ld \n", t2-t1);
        return 0;
    }
}

答案 2 :(得分:1)

您的代码中存在多个问题:

  • 以读取+更新模式("r+")打开文件很棘手:必须在读取和写入操作之间调用fseek(),否则行为未定义。此外,您必须以二进制模式打开文件,fseek()才能在字节偏移上正确且可移植地运行。

  • ch必须定义为int才能正确检测EOF

  • 'a''z'的值硬编码为96123是不可移植且容易出错的,事实上'a'是{{ 1}}在ASCII中,不是9796'z',而不是122。使用123中的函数可获得最佳的可移植性和可读性。

  • <ctype.h>移位仅适用于ASCII,请改用32

  • 您忘记包含声明toupper()功能的<stdlib.h>

这是一个更正(简单和低效)的版本:

exit()

答案 3 :(得分:0)

使用toupper(3)中的#include <ctype.h>功能(或微距呼叫),因此您无需知道安装时可用的字符集。

#include <stdio.h>

int main() {
    FILE *file;
    int ch;
    file = fopen("file.txt", "r+");
    if (file == NULL) {
        printf("Error");
        exit(1);
    } else {
        while ((ch = fgetc(file)) != EOF) {
            putc(toupper(ch), file);
        }
        fclose(file);
        return 0;
    }
}

您的原始代码存在缺陷...您将ch检查为小写,并且只有在恰好时输出它。您还必须输出所有大写和无大小写字符....所以不要将putc(3)调用放在if块中。我的代码只输出用函数转换为大写的所有字符。此外,您必须根据chintfgetc(3)的要求将toupper(3)定义为putc(3)