У меня есть тема, в которой меня просят прочитать файл c, преобразовать его комментарии из нижнего регистра в верхний и наоборот, а затем сохранить этот файл с любыми изменениями, внесенными в другой файл c (например, пустой выходной файл). Я сделал код, но он не вносит никаких изменений в комментарии, вместо этого он сохраняет исходный файл в файле output.c, какие-либо предложения?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char ch;
FILE *fp1, *fp2;
char source_file[] = "input2.c";
char target_file[] = "output.c";
char str[200];
fp1 = fopen(source_file, "r");
fp2 = fopen(target_file, "w");
while(fgets(str,200,fp1) != NULL){
int i,j,l;
int l = strlen(str);
for(int i = 0; i < l-1; i++){
if (str[i]=='/' && str[i+1]=='/'){
for(int j = i+2; j < l; j++){
if (str[j] >= 'A' && str[j]<='Z')
str[j] = str[j] + 32;
else if (str[j] >= 'a' && str[j]<='z')
str[j] = str[j] - 32;
}
}
}
}
while ((ch = fgetc(fp1)) != EOF)
{fputc(ch, fp2);
printf("File copied successfully.\n");}
fclose(fp1);
fclose(fp2);
return 0;
}
Вы читаете каждую строку в str и изменяете ее внутри цикла while. Однако вы никогда не записываете это измененное содержимое в новый файл и не сохраняете его где-либо.
Есть несколько способов сделать это. Я бы рекомендовал писать каждую строку внутри цикла while.
Что вы имеете в виду, написав каждую строку внутри цикла while, как мне это сделать?
Попробуй это:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char ch;
FILE *fp1, *fp2;
char source_file[] = "input2.c";
char target_file[] = "output.c";
char str[200];
fp1 = fopen(source_file, "r");
fp2 = fopen(target_file, "w");
while(fgets(str,200,fp1) != NULL){
int flag = 0;
int l = strlen(str);
for(int i = 0; i < l-1; i++){
if (str[i]=='/' && str[i+1]=='/'){
for(int j = i+2; j < l; j++){
if (str[j] >= 'A' && str[j]<='Z')
str[j] = str[j] + 32;
else if (str[j] >= 'a' && str[j]<='z')
str[j] = str[j] - 32;
}
fprintf(fp2,"%s",str);
flag = 1;
}
if (i == l-2)
fprintf(fp2,"%s",str);
if (flag == 1)
break;
}
}
printf("File copied successfully.\n");
fclose(fp1);
fclose(fp2);
return 0;
}
визуальный код, похоже, не распознает bool, true и false
@ ΓιωργοςΙωαννιδης Вы имеете в виду не использовать «логический флаг»?
когда я использую код, который вы мне дали, я получаю эти ошибки: идентификатор «флаг» не определен, идентификатор «ложь» не определен, идентификатор «истина» не определен.
Любопытно, код использует 'A'
и 'a'
, почему код с магическим числом 32
, а не ('a' - 'A')
?
Я искал в Интернете, чтобы получить помощь с прописными буквами в строчные и наоборот, и нашел метод, используемый в коде.
@ΓιωργοςΙωαννιδης Я редактировал. Попробуйте еще раз
Я только что сделал, проблема в том, что код ничего не вставляет в выходной файл
Я выполнил код, и он абсолютно правильный. Вы должны сначала закрыть файл output.c, запустить код, который я отправил, а затем открыть файл output.c. Другими словами, сначала запустите код, а затем откройте файл output.c.
да, вы правы, мой плохой, я заметил, что output.c содержит только измененные строки, как мне сделать так, чтобы в выходном файле было все содержимое кода, а также изменения в комментариях, которые применяется в коде
Вы имеете в виду, что файл output.c содержит исходный код, а также комментарии до и после изменений?
Чтобы быть конкретным, мне нужно, чтобы файл output.c содержал исходный код, а также комментарии после изменений, если у вас есть время, чтобы сделать это, я буду более чем счастлив
Дай мне подумать. я скажу тебе
@ΓιωργοςΙωαννιδης Отредактировано. Сейчас все хорошо. Попробуй это :)
Линия
while ((ch = fgetc(fp1)) != EOF)
работать не будет по двум причинам:
Индикатор позиции файла уже находится в конце файла, потому что ваш код достигнет этой строки только после того, как fgets
вернет NULL
.
Даже если вы переместите позицию файла в начало файла с помощью rewind
, ваш цикл не будет работать, потому что вы внесли изменения в str
, а не во входной файл. Поэтому вы хотите записать str
в выходной файл, а не копировать входной файл.
По причинам, изложенным выше, вы должны удалить этот цикл и вместо этого вставить строку fputs( str, fp2 );
в цикл fgets
:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
FILE *fp1, *fp2;
char source_file[] = "input2.c";
char target_file[] = "output.c";
char str[200];
fp1 = fopen(source_file, "r");
fp2 = fopen(target_file, "w");
while(fgets(str,200,fp1) != NULL){
int l = strlen(str);
for(int i = 0; i < l-1; i++){
if (str[i]=='/' && str[i+1]=='/'){
for(int j = i+2; j < l; j++){
if (str[j] >= 'A' && str[j]<='Z')
str[j] = str[j] + 32;
else if (str[j] >= 'a' && str[j]<='z')
str[j] = str[j] - 32;
}
}
}
//INSERTED_CODE
fputs( str, fp2 );
//INSERTED CODE
}
fclose(fp1);
fclose(fp2);
return 0;
}
Для ввода
This is a test. //This is a test.
программа имеет следующий (правильный) вывод:
This is a test. //tHIS IS A TEST.
Кстати, вот как я бы написал решение:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define INPUT_FILENAME "input2.c"
#define OUTPUT_FILENAME "output.c"
int main( void )
{
FILE *fp1, *fp2;
char line[200];
//attempt to open input file
fp1 = fopen( INPUT_FILENAME, "r" );
if ( fp1 == NULL )
{
fprintf( stderr, "Error opening input file!\n" );
exit( EXIT_FAILURE );
}
//attempt to open input file
fp2 = fopen( OUTPUT_FILENAME, "w" );
if ( fp2 == NULL )
{
fprintf( stderr, "Error opening output file!\n" );
exit( EXIT_FAILURE );
}
//read one line per loop iteration
while( fgets( line, sizeof line, fp1 ) != NULL )
{
char *p;
//verify that input buffer was large enough to fit
//the entire line
if ( strchr( line, '\n' ) == NULL )
{
fprintf( stderr, "Line was too long for input buffer!\n" );
exit( EXIT_FAILURE );
}
//determine whether line contains comment
if ( ( p = strstr( line, "//" ) ) != NULL )
{
//skip the "//"
p += 2;
//make comment upper-case
for ( ; *p != '\0'; p++ )
{
//reverse the case if character is alphabetical
if ( islower( (unsigned char)*p ) )
*p = toupper( (unsigned char)*p );
else if ( isupper( (unsigned char)*p ) )
*p = tolower( (unsigned char)*p );
}
}
//write (possibly modified) line to output file
fputs( line, fp2 );
}
//cleanup
fclose(fp2);
fclose(fp1);
return EXIT_SUCCESS;
}
Однако обратите внимание, что в C есть два возможных комментария:
//
/*
и */
Похоже, вы обрабатываете только первый тип комментариев. Если вы хотите также иметь возможность обрабатывать комментарии второго типа, то решение будет более сложным (но также возможным).
Ваш опубликованный код не компилируется, потому что переменная
l
объявлена дважды.