简体   繁体   中英

C change words beginning with lowercase to capital in text file

Well I try to read a file and change every word that's beginning with a lowercase to the same word beginning with an uppercase.

This is what i got:

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

My test.txt file does not change at all.

Any suggestions what i am doing wrong?

EDIT:

Thank you for the different ways to achieve my task.

Most of them where using stuff i didn't learn yet, so i tried it by copying the characters from one file to another + making the first letter of each word an uppercase by toupper() cause it's indeed easy to use. Then deleting the old file + rename the new one.

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

Let us say a word begins with a letter after a space (or white-space) or at file beginning.

Look for the pattern <space><lowercase>

Seeking relative to SEEK_CUR should be avoided for text files.

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's code had trouble as fseek() was not needed and ('a' <= zeichen) && (zeichen <= 'z') is always false (in ASCII) as ' ' is not between 'a' and 'z' .

    if(zeichen == ' '){
        fseek(fp, 1L, SEEK_CUR);
        if(('a' <= zeichen) && (zeichen <= 'z')){
            zeichen = fgetc(fp);
            fputc(toupper(zeichen), fp);
        }
    }
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;

you can use std out redirection ./main > output.txt

Your code is a bit of an overkill, let alone some things I am not that smart to understand (for example why you are checking for the space character, why the condition of checking for a lowercase is ('a' <= zeichen) && (zeichen <= 'z') and not 'a' >= ... ). Moreover the non-universal language makes it tough for me. Some of them are already explained in the comments, so I will try to explain what I would do.

I wouldn't try to fseek() all the time, I would read the file once and then write the data once again. Here is my algorithm:

  1. Read file line by line.
  2. Store every word in a 2D array.
  3. Check if a word starts with a lowercase, and if so swap that lowercase letter with an uppercase one.
  4. Now the array holds all the data I need to write to the file.
  5. Set the file pointer to the start of the file.
  6. Iterate over the stored words in the array and write them to file.

Here is my implementation:

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

which will overwrite the contents of this file:

Manu
Samaras
small

to this:

Manu
Samaras
Small

Apart from that focusing on words you can achieve more secure results, if your file contains only space separated words, you can rely on first letter after space character.

You tried to use the fseek which is not not bad at all but I would use it differently:

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

Stepping back after reading the first letter next to a space is important, because fgetc (and fputc too) autmatically step the cursor forward after reading. So, to rewrite the current letter to its upper case counterpart, you have to step back the cursor.

The shortcomings of my example are that it won't change the first letter of the first word in a file and it's important to the file should not end with a space but with a word.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM