Reputation:
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;
}
Upvotes: 1
Views: 1362
Reputation: 4473
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.
Upvotes: 1
Reputation: 1105
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
Upvotes: 0
Reputation: 154325
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);
}
}
Upvotes: 1
Reputation: 73384
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:
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
Upvotes: 0