C将文本文件中以小写字母开头的单词更改为大写字母

时间:2017-06-28 20:58:30

标签: c string file uppercase fseek

好吧,我尝试读取一个文件,将每个以小写字母开头的单词改为以大写字母开头的同一个单词。

这就是我得到的:

#include <stdio.h>
#include <stdlib.h>

int main()
{
FILE *fp;
int zeichen;

fp = fopen("test.txt", "r+");

if(fp == NULL){
    printf("Die Datei konnte nicht geoeffnet werden.\n");
}
else{
    fseek(fp, 0L, SEEK_SET);
    zeichen = fgetc(fp);
    while(zeichen != EOF){
        if(zeichen == ' '){
            fseek(fp, 1L, SEEK_CUR);
            if(('a' <= zeichen) && (zeichen <= 'z')){
                zeichen = fgetc(fp);
                fputc(toupper(zeichen), fp);
            }
        }
        zeichen = fgetc(fp);
    }
    zeichen = fgetc(fp);
    fclose(fp);
}
return 0;
}

我的test.txt文件根本没有变化。

有什么建议我做错了吗?

编辑:

感谢您完成任务的不同方法。

他们中的大多数人使用的东西我还没有学习,所以我尝试将字符从一个文件复制到另一个文件+使每个单词的第一个字母由toupper()大写为大写因为它&#39;确实很容易使用。然后删除旧文件+重命名新文件。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main()
{
    FILE *fp, *neu;
    int zeichen;

    fp = fopen("test.txt", "r");
    neu = fopen("new.txt", "w");

    if(fp == NULL) {
        printf("Die Datei konnte nicht geoeffnet werden.\n");
        exit(EXIT_FAILURE);
    }

    while((zeichen = fgetc(fp)) != EOF) {
        if(zeichen == ' ') {
            fputc(zeichen, neu);
            zeichen = fgetc(fp);
            zeichen = toupper(zeichen);
            fputc(zeichen, neu);
        }
        else{
            fputc(zeichen, neu);
        }
    }
    fclose(fp);
    fclose(neu);
    remove("test.txt");
    rename("new.txt", "test.txt");
    printf("File has been changed.\n");
    return 0;
}

4 个答案:

答案 0 :(得分:1)

让我们说单词以空格(或空格)后面的字母或文件开头的字母开头。

寻找模式<space><lowercase>

对于文本文件,应避免与SEEK_CUR相关。

bool previous_space = true;
long offset = ftell(fp);  // remember where we are
while(offset != -1 && (zeichen = fgetc(fp)) != EOF) {
  if (previous_space && islower(zeichen)) {
    fseek(fp, offset, SEEK_SET); 
    fputc(toupper(zeichen), fp);
  }
  previous_space = isspace(zeichen);
  offset = ftell(fp);
}

OP的代码出现问题,因为fseek()不需要,('a' <= zeichen) && (zeichen <= 'z')始终为false(以ASCII格式显示),因为' '不在'a'和{{'z'之间1}}。

    if(zeichen == ' '){
        fseek(fp, 1L, SEEK_CUR);
        if(('a' <= zeichen) && (zeichen <= 'z')){
            zeichen = fgetc(fp);
            fputc(toupper(zeichen), fp);
        }
    }

答案 1 :(得分:1)

FILE *fp;
int zeichen;

fp = fopen("test.txt", "r+");

if (fp == NULL) {
    printf("Die Datei konnte nicht geoeffnet werden.\n");
    exit(EXIT_FAILURE);
}

// upper first charcter
zeichen = getc(fp);
if (zeichen != EOF) putchar(toupper(zeichen));

// scan rest of chars
while ((zeichen = getc(fp)) != EOF) {
    putchar(zeichen);
    if (zeichen == ' ' && zeichen != EOF) {
        char c_upper = getc(fp);
        putchar(toupper(c_upper));
    }
}
fclose(fp);
return 0;

你可以使用std out重定向./main&gt; output.txt的

答案 2 :(得分:0)

你的代码有点矫枉过正,更不用说一些我不太懂的东西了(例如为什么要检查空格字符,为什么检查小写的条件是('a' <= zeichen) && (zeichen <= 'z')和不是'a' >= ...)。而且,非通用语言对我来说很难。其中一些已在评论中解释,所以我将尝试解释我会做什么。

我不会一直尝试fseek(),我会读取文件一次,然后再次写入数据。这是我的算法:

  1. 逐行阅读文件。
  2. 将每个单词存储在2D数组中。
  3. 检查一个单词是否以小写字母开头,如果是,则交换该单词 带小写字母的小写字母。
  4. 现在数组包含我需要写入文件的所有数据。
  5. 将文件指针设置为文件的开头。
  6. 迭代数组中存储的单词并将其写入文件。
  7. 这是我的实施:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    #define MAX 5   // max number of words to be read
    #define LEN 10  // max lenght of a word allowed
    
    int main(void)
    {
        FILE* fp = fopen("test.txt", "r+");
        char buffer[MAX][LEN]; // read up to 5 words, of at most 10 characters
        if (fp == NULL)
            exit(EXIT_FAILURE);
        int count = 0;
        while(count < MAX && fgets(buffer[count], LEN, fp)) {
            if(buffer[count][strlen(buffer[count]) - 1] == '\n') buffer[count][strl$
            //printf("%s\n", buffer[count]);
            if(islower(buffer[count][0]))
                buffer[count][0] = (char)toupper(buffer[count][0]);
            //printf("%s\n", buffer[count]);
            count++;
        }
    
        fseek(fp, 0, SEEK_SET);
        for(int i = 0; i < count; ++i)
            fprintf(fp, "%s\n", buffer[i]);
    
    
        fclose(fp);
        return 0;
    }
    

    将覆盖此文件的内容:

    Manu
    Samaras
    small
    

    到此:

    Manu
    Samaras
    Small
    

答案 3 :(得分:0)

除了专注于单词,你可以获得更安全的结果,如果你的文件只包含空格分隔的单词,你可以依赖空格字符后面的第一个字母。

你试图使用fseek,但这完全不差,但我会以不同的方式使用它:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main() {
    FILE* fp;
    int zeichen;

    fp = fopen("test.txt", "r+");
    if(fp == NULL) {
        printf("Die Datei konnte nicht geoeffnet werden.\n");
        exit(EXIT_FAILURE);
    }

    while((zeichen = fgetc(fp)) != EOF) {
        if(zeichen == ' ') {
            zeichen = fgetc(fp);
            fseek(fp, -1, SEEK_CUR);
            fputc(toupper(zeichen), fp);
        }
    }

    fclose(fp);
    return 0;
}

阅读空格旁边的第一个字母后退一步很重要,因为fgetc(以及fputc)也会在阅读后自动向前移动光标。因此,要将当前字母重写为大写字母,您必须退回光标。

我的例子的缺点是它不会改变文件中第一个单词的第一个字母,重要的是文件不应该以空格结尾,而应该以单词结尾。