Невозможно внести изменения и сохранить в выходной файл на C

У меня есть тема, в которой меня просят прочитать файл 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;
}

Ваш опубликованный код не компилируется, потому что переменная l объявлена ​​дважды.

Andreas Wenzel 09.04.2022 21:14
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
2
1
43
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы читаете каждую строку в str и изменяете ее внутри цикла while. Однако вы никогда не записываете это измененное содержимое в новый файл и не сохраняете его где-либо.

Есть несколько способов сделать это. Я бы рекомендовал писать каждую строку внутри цикла while.

Что вы имеете в виду, написав каждую строку внутри цикла while, как мне это сделать?

Γιωργος Ιωαννιδης 09.04.2022 19:12

Попробуй это:

#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

Γιωργος Ιωαννιδης 09.04.2022 19:26

@ ΓιωργοςΙωαννιδης Вы имеете в виду не использовать «логический флаг»?

Ali 09.04.2022 19:31

когда я использую код, который вы мне дали, я получаю эти ошибки: идентификатор «флаг» не определен, идентификатор «ложь» не определен, идентификатор «истина» не определен.

Γιωργος Ιωαννιδης 09.04.2022 19:32

Любопытно, код использует 'A' и 'a', почему код с магическим числом 32, а не ('a' - 'A')?

chux - Reinstate Monica 09.04.2022 19:35

Я искал в Интернете, чтобы получить помощь с прописными буквами в строчные и наоборот, и нашел метод, используемый в коде.

Γιωργος Ιωαννιδης 09.04.2022 19:37

@ΓιωργοςΙωαννιδης Я редактировал. Попробуйте еще раз

Ali 09.04.2022 19:47

Я только что сделал, проблема в том, что код ничего не вставляет в выходной файл

Γιωργος Ιωαννιδης 09.04.2022 19:55

Я выполнил код, и он абсолютно правильный. Вы должны сначала закрыть файл output.c, запустить код, который я отправил, а затем открыть файл output.c. Другими словами, сначала запустите код, а затем откройте файл output.c.

Ali 09.04.2022 20:01

да, вы правы, мой плохой, я заметил, что output.c содержит только измененные строки, как мне сделать так, чтобы в выходном файле было все содержимое кода, а также изменения в комментариях, которые применяется в коде

Γιωργος Ιωαννιδης 09.04.2022 20:23

Вы имеете в виду, что файл output.c содержит исходный код, а также комментарии до и после изменений?

Ali 09.04.2022 21:03

Чтобы быть конкретным, мне нужно, чтобы файл output.c содержал исходный код, а также комментарии после изменений, если у вас есть время, чтобы сделать это, я буду более чем счастлив

Γιωργος Ιωαννιδης 09.04.2022 21:32

Дай мне подумать. я скажу тебе

Ali 09.04.2022 22:07

@ΓιωργοςΙωαννιδης Отредактировано. Сейчас все хорошо. Попробуй это :)

Ali 09.04.2022 22:16
Ответ принят как подходящий

Линия

while ((ch = fgetc(fp1)) != EOF)

работать не будет по двум причинам:

  1. Индикатор позиции файла уже находится в конце файла, потому что ваш код достигнет этой строки только после того, как fgets вернет NULL.

  2. Даже если вы переместите позицию файла в начало файла с помощью 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 есть два возможных комментария:

  1. однострочные комментарии //
  2. многострочные комментарии /* и */

Похоже, вы обрабатываете только первый тип комментариев. Если вы хотите также иметь возможность обрабатывать комментарии второго типа, то решение будет более сложным (но также возможным).

Другие вопросы по теме