【问题标题】:C change words beginning with lowercase to capital in text fileC将文本文件中以小写开头的单词更改为大写
【发布时间】:2017-06-28 20:58:29
【问题描述】:

我尝试读取一个文件并将每个以小写开头的单词更改为以大写开头的同一个单词。

这是我得到的:

#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() 使每个单词的第一个字母大写,因为它确实很容易使用。然后删除旧文件+重命名新文件。

#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;
}

【问题讨论】:

  • if(zeichen == ' ') toupper()吗?
  • 我的目的是检查字符是否为空格,如果是,则向前移动一个字符并将其打印在与大写字母相同的位置。
  • 显然你需要else { fputc(zeichen, fp); }` 子句。
  • 看if(zeichen == ' '){ fseek(fp, 1L, SEEK_CUR); if(('a' &lt;= zeichen) &amp;&amp; (zeichen &lt;= 'z')){,zeichen在第一个if()之后没有变化
  • 一般来说,这对文本文件(读取和写入)来说是一件奇怪的事情,通常会读取文件并写入一个新文件,并在您进行更改时进行更改(您似乎试图用你的 else 子句做)。然后将新文件重命名为旧文件。另请注意,正如 dhke 指出的那样,您的代码是错误的,如果它们是 ' ',您只会查看字符

标签: c string file uppercase fseek


【解决方案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;

你可以使用标准输出重定向 ./main > output.txt

【讨论】:

    【解决方案2】:

    假设一个单词以空格(或空白)后或文件开头的字母开头。

    寻找模式&lt;space&gt;&lt;lowercase&gt;

    对于文本文件,应避免相对于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' &lt;= zeichen) &amp;&amp; (zeichen &lt;= 'z') 始终为 false(在 ASCII 中),因为 ' ' 不在 'a' 和 'z' 之间。

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

    【讨论】:

    • 琐事:如果ch 是一个字母A-Z,a-z,ch ^= 'A' ^ 'a'; 将改变ASCII、EBCDIC 和大多数独角兽编码中的大小写。字母大小写之间有一致的位差。
    【解决方案3】:

    您的代码有点矫枉过正,更不用说一些我不太聪明理解的事情(例如,为什么要检查空格字符,为什么检查小写的条件是('a' &lt;= zeichen) &amp;&amp; (zeichen &lt;= 'z') 而不是@ 987654322@)。此外,非通用语言对我来说很难。其中一些已经在 cmets 中进行了解释,因此我将尝试解释我会做什么。

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

    1. 逐行读取文件。
    2. 将每个单词存储在二维数组中。
    3. 检查单词是否以小写字母开头,如果是则交换 小写字母加大写字母。
    4. 现在数组保存了我需要写入文件的所有数据。
    5. 将文件指针设置为文件的开头。
    6. 遍历数组中存储的单词并将它们写入文件。

    这是我的实现:

    #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
    

    【讨论】:

    • 不会 fgets(buffer[count], LEN, fp) 在 "abcd efg hijk\n"` 中拆分像 "hijk" 这样的词。
    • 但是 OP 说该文件包含单词@chux。除非文件包含文本并且他的意思是一般的每个单词。在这种情况下是的,应该遵循你的回答(我没有投票权)。 ://
    【解决方案4】:

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

    您尝试使用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)在读完后会自动向前移动光标。因此,要将当前字母改写为大写字母,您必须后退光标。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      • 1970-01-01
      • 2018-05-05
      • 1970-01-01
      • 2019-06-15
      • 1970-01-01
      相关资源
      最近更新 更多