C将文本文件中以小写字母开头的单词更改为大写字母
C change words beginning with lowercase to capital in text file
好吧,我尝试读取一个文件并将以小写字母开头的每个单词更改为以大写字母开头的同一个单词。
这是我得到的:
#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;
}
假设一个 word 以 space(或 white-space)之后或文件开头的字母开头。
寻找模式<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')
始终为假(在 ASCII 中),因为 ' '
不在 'a'
和 [=18= 之间].
if(zeichen == ' '){
fseek(fp, 1L, SEEK_CUR);
if(('a' <= zeichen) && (zeichen <= 'z')){
zeichen = fgetc(fp);
fputc(toupper(zeichen), fp);
}
}
你的代码有点矫枉过正,更不用说一些我不太理解的东西了(例如你为什么要检查 space 字符,为什么检查小写的条件是('a' <= zeichen) && (zeichen <= 'z')
而不是 'a' >= ...
)。此外,非通用语言让我很难接受。其中一些已经在评论中进行了解释,所以我将尝试解释我会做什么。
我不会一直尝试fseek()
,我会读取一次文件然后再次写入数据。这是我的算法:
- 逐行读取文件。
- 将每个单词存储在二维数组中。
- 检查单词是否以小写开头,如果是则交换
小写字母加大写字母。
- 现在数组包含我需要写入文件的所有数据。
- 将文件指针设置为文件的开头。
- 遍历数组中存储的单词并将它们写入文件。
这是我的实现:
#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
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
除了关注单词可以获得更安全的结果,如果您的文件仅包含 space 个分隔的单词,您可以依赖 space 个字符后的第一个字母。
您尝试使用 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;
}
阅读 space 旁边的第一个字母后退回很重要,因为 fgetc
(and fputc
也是)阅读后自动向前移动光标。因此,要将当前字母重写为对应的大写字母,您必须后退光标。
我的示例的缺点是它不会更改文件中第一个单词的首字母,重要的是文件不应以 space 结尾,而应以单词结尾。
好吧,我尝试读取一个文件并将以小写字母开头的每个单词更改为以大写字母开头的同一个单词。
这是我得到的:
#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;
}
假设一个 word 以 space(或 white-space)之后或文件开头的字母开头。
寻找模式<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')
始终为假(在 ASCII 中),因为 ' '
不在 'a'
和 [=18= 之间].
if(zeichen == ' '){
fseek(fp, 1L, SEEK_CUR);
if(('a' <= zeichen) && (zeichen <= 'z')){
zeichen = fgetc(fp);
fputc(toupper(zeichen), fp);
}
}
你的代码有点矫枉过正,更不用说一些我不太理解的东西了(例如你为什么要检查 space 字符,为什么检查小写的条件是('a' <= zeichen) && (zeichen <= 'z')
而不是 'a' >= ...
)。此外,非通用语言让我很难接受。其中一些已经在评论中进行了解释,所以我将尝试解释我会做什么。
我不会一直尝试fseek()
,我会读取一次文件然后再次写入数据。这是我的算法:
- 逐行读取文件。
- 将每个单词存储在二维数组中。
- 检查单词是否以小写开头,如果是则交换 小写字母加大写字母。
- 现在数组包含我需要写入文件的所有数据。
- 将文件指针设置为文件的开头。
- 遍历数组中存储的单词并将它们写入文件。
这是我的实现:
#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
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
除了关注单词可以获得更安全的结果,如果您的文件仅包含 space 个分隔的单词,您可以依赖 space 个字符后的第一个字母。
您尝试使用 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;
}
阅读 space 旁边的第一个字母后退回很重要,因为 fgetc
(and fputc
也是)阅读后自动向前移动光标。因此,要将当前字母重写为对应的大写字母,您必须后退光标。
我的示例的缺点是它不会更改文件中第一个单词的首字母,重要的是文件不应以 space 结尾,而应以单词结尾。