我正在尝试使用C来改变文件中第一个字母的大小写。
例如,如果文件包含句子:good morning.how are you?
然后它将更改为Good Morning.How Are You?
我尝试了很多,但无法产生预期的效果。 谁能帮我?我使用这段代码:
#include <stdio.h>
void main() {
FILE *fp1;
char ch;
int p;
fp1 = fopen("asiftext.txt", "a+");
ch = fgetc(fp1);
if (ch >= 'a' && ch <= 'z') {
fseek(fp1, -1, 1);
ch = toupper(ch);
fputc(ch, fp1);
}
while ((ch = fgetc(fp1)) != EOF) {
if (ch == ' ' || ch == '\n') {
ch = fgetc(fp1);
if (ch == EOF)
break;
if (ch >= 97 && ch <= 122) {
fseek(fp1, -1, 1);
fputc(ch - 32, fp1);
}
}
}
/*ch = fgetc(fp1);
p = ftell(fp1);
printf("p1=%d", p);
printf("%c\n", ch);
fseek(fp1, -1, 1);
fputc(ch - 32,fp1);
ch = fgetc(fp1);
printf("c=%c\n", ch); */
fclose(fp1);
}
答案 0 :(得分:0)
修改文件是个坏主意。为此使用标准流是麻烦且低效的。
这是一个简单的过滤器,可以读取stdin
并将修改过的单词写入stdout
:
#include <ctype.h>
#include <stdio.h>
int main(void) {
int c, lastc = '\n';
while ((c = getchar()) != EOF) {
if (!isalpha(lastc))
c = toupper(c);
putchar(c);
lastc = c;
}
return 0;
}
请注意,上述代码适用于ASCII文本文件。它可能不适用于非ASCII文件,特别是如果它们使用UTF-8等多字节编码进行编码。
答案 1 :(得分:0)
转换为标题案例时出现的一个问题是,“在一个单词中触发第一个字符大写的可接受的前面字符是什么?”有时,如您的示例中所示,您可能希望将Morning.How
与how
视为单独的单词并大写。其他时候,您可能只想考虑空格后的单词。
您可以通过指定一个结尾字符列表(下面为ends
)来定制,然后将第一个字符转换为大写字母。您可以设置定义字符串常量的宏,将第二个短字符串传递给您的标题函数,或者只在函数本身中指定ends
列表。
通常,我不会在由点分隔符组成的字符串中大写,但它没有任何问题。这就是ends
列表的灵活性带来红利的地方。您只需定制字符串以满足您的需求。一个例子是:
/** convert string to title case based on 'ends'.
* returns pointer to 'str' with words converted to
* initial uppercase if the word follows one of the
* characters specified in 'ends'.
*/
char *str2title (char *str)
{
if (!str) return NULL; /* handle NULL and empty-string */
if (!*str) return str;
char *p = str, /* pointer to string */
*ends = " \t\n.", /* set of acceptable ends */
last = ' '; /* previous character seen */
for (; *p; p++) { /* loop over string */
for (char *e = ends; *e; e++) /* loop over ends */
/* if last is end and current is lowercase */
if (last == *e && ('a' <= *p && *p <= 'z'))
*p += 'A' - 'a'; /* convert to upper */
last = *p;
}
return str;
}
有很多方法可以解决这个问题。向他们学习。
答案 2 :(得分:-1)
以下提议的代码:
ctype.h
中的设施来避免加密数字等现在,建议的代码:
#include <stdio.h> // fopen(), perror(), fgetc(), fclose(),
// fseek(), fputc(),
// FILE, EOF
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <ctype.h> // toupper(), isspace(), isalpha()
int main( void )
{
int ch;
FILE *fp1 = fopen( "asiftext.txt", "r+" );
if( !fp1 )
{
perror( "fopen failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
while( ( ch = fgetc( fp1 ) ) != EOF )
{
if( !isspace( ch ) )
{
continue;
}
// when here, 'ch' is a 'white space' char
if( ( ch = fgetc( fp1 ) ) == EOF )
{
break;
}
// when here, 'ch' is possibly the
// first letter of a word
if( isalpha( ch ) )
{ // then 'ch' is alphabetic
// adjust file pointer
if( fseek( fp1, -1, SEEK_CUR ) )
{
perror( "fseek failed" );
fclose( fp1 );
exit( EXIT_FAILURE );
}
// implied else, fseek successful
// overwrite with uppercase char
fputc( toupper( ch ), fp1 );
}
}
fclose(fp1);
}
以下提出的代码实现了一个(两个状态)状态机,并解决了OPs算法的缺点。
#include <stdio.h> // fopen(), perror(), fgetc(), fclose(),
// fseek(), fputc(),
// FILE, EOF
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <ctype.h> // toupper(), isspace(), isalpha()
enum state { notInWord, InWord };
int main( void )
{
enum state currentState = notInWord;
int ch;
FILE *fp1 = fopen( "asiftext.txt", "r+" );
if( !fp1 )
{
perror( "fopen failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
while( (ch = fgetc( fp1 ) ) != EOF )
{
if( notInWord == currentState )
{
if( isalpha( ch ) )
{
currentState = InWord;
// adjust file pointer
if( fseek( fp1, -1, SEEK_CUR ) )
{
perror( "fseek failed" );
fclose( fp1 );
exit( EXIT_FAILURE );
}
// implied else, fseek successful
// overwrite with uppercase char
fputc( toupper( ch ), fp1 );
}
else // not alpha
{
currentState = notInWord;
}
}
else // currentState = InWord
{
if( !isalpha( ch ) )
{
currentState = notInWord;
}
}
}
fclose(fp1);
}
这是在更正的源代码副本运行时更正的代码的输出:
#Include <Stdio.H> // Fopen(), Perror(), Fgetc(), Fclose(),
// Fseek(), Fputc(),
// FILE, EOF
#Include <Stdlib.H> // Exit(), EXIT_FAILURE
#Include <Ctype.H> // Toupper(), Isspace(), Isalpha()
Enum State { NotInWord, InWord };
Int Main( Void )
{
Enum State CurrentState = NotInWord;
Int Ch;
FILE *Fp1 = Fopen( "Asiftext.Txt", "R+" );
If( !Fp1 )
{
Perror( "Fopen Failed" );
Exit( EXIT_FAILURE );
}
// Implied Else, Fopen Successful
While( (Ch = Fgetc( Fp1 ) ) != EOF )
{
If( NotInWord == CurrentState )
{
If( Isalpha( Ch ) )
{
CurrentState = InWord;
// Adjust File Pointer
If( Fseek( Fp1, -1, SEEK_CUR ) )
{
Perror( "Fseek Failed" );
Fclose( Fp1 );
Exit( EXIT_FAILURE );
}
// Implied Else, Fseek Successful
// Overwrite With Uppercase Char
Fputc( Toupper( Ch ), Fp1 );
}
Else // Not Alpha
{
CurrentState = NotInWord;
}
}
Else // CurrentState = InWord
{
If( !Isalpha( Ch ) )
{
CurrentState = NotInWord;
}
}
}
Fclose(Fp1);
}