Работа с файлами и командной строкой - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Добрый день. В Си совсем новичок, прошу помощи, хочу и нужно разобраться. Стоит такая задача: произвести копирование файла (например, in.txt) и назвать out.txt через *arvg[], а затем сделать проверку: если файл не существует, копировать, если существует - удалить и копировать. Пока написал такой код:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h> 
#include <share.h> 
#define _CRT_SECURE_NO_WARNINGS
int main(int argc, char* argv[])
{
    int in, out;
    int  n = 0;
    char buf[4096], p;
    
    errno_t errno_1 = _sopen_s(&in, argv[1], O_RDONLY, _SH_DENYNO, 0); //_SH_DENYRW
    errno_t errno_2 = _sopen_s(&out, argv[2], O_WRONLY | O_RDONLY | O_TRUNC | O_CREAT, _SH_DENYNO, 0); 
 
    //FILE * in = fopen_s(&in, argv[1], 'r');
    //FILE * out = fopen_s(&out, argv[2], 'w');
 
    printf("%d\n",_access(argv[2], 0));
 
    if (_access(argv[2], 0) != -1) //0 - exist , 02 - access, 04 - read, 06 - read and write
    {
        while ((n = _read(in, buf, sizeof buf)) > 0) 
        {
            _write(out, buf, n);
        }
        printf("File %s\nwas successfully copied as: \n%s\n", argv[1], argv[2]);
    }
    else //if (_access(argv[2], 0) != 0)
    {
        printf("Would you like to re-write the file? Press 'y' to confirm and 'no' to refuse\n");
        scanf_s(&p);
        
        while ((p == 'y') || (p == 'n'))
        {
            if (p == 'y')
            {
                remove(argv[2]);
                if (remove(argv[2]) == -1)
                {
                    printf("Copying...\n");
                }
                else
                {
                    printf("Removed\n");
                }
                printf("File %s \n...was successfully copied as: \n%s\n", argv[1], argv[2]);
            }
            else if (p == 'n')
            {
                exit(1);
            }
        }
    }
    system("pause");
    return 0;
}
Как результат, просто копирование выполняется, но на следующем выполнении останавливается в первом цикле while. Visual Studio 2015. Сразу поясню насчет функций open: fopen отказывается работать, требует fopen_s, но с ней тоже не получилось реализовать. Лишь с помощью функции _sopen_s удалось хоть что-то реализовать (было долго и мучительно). Буду благодарен за разъяснения.

Решение задачи: «Работа с файлами и командной строкой»

textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h> 
#include <string.h>
#include <share.h> 
 
#define ORG_FILE argv[0]
#define INP_FILE argv[1]
#define OUT_FILE argv[2]
 
int main(int argc, char* argv[])
{
    FILE * in = 0;
    FILE * out = 0;
    size_t bytes;
    unsigned char buf[4096] = { 0 };
    printf("Number of arguments: %d\n",argc);
    printf("Function name: %s\n", ORG_FILE);
    
    printf("Enter input file: ");
    INP_FILE = scanf_s(&INP_FILE);
    printf_s("Enter output file: ");
    OUT_FILE = scanf_s(&OUT_FILE);
    
    errno_t ein = fopen_s(&in, INP_FILE, "rb");
    if (!ein)
    {
        printf("Open in: done...\n");
    }
    else
    {
        fprintf(stderr, "Open in: error...\n", INP_FILE);
        return 1;
    }
 
#ifdef _DEBUG
    system("pause");
#endif
 
    errno_t eout = fopen_s(&out, OUT_FILE, "wb");
    if (!eout)
    {
        printf("Open out: done...\n");
    }
    else
    {
        fprintf(stderr, "Open out: error...\n", OUT_FILE);
        return 1;
    }
 
#ifdef _DEBUG
    system("pause");
#endif
 
    while ((bytes = fread(buf, sizeof(char), 4096, in)) && bytes > 0)
    {
        if (fwrite(buf, sizeof(char), bytes, out) != bytes)
        {
            fprintf(stderr, "Can't be written to %s!\n", OUT_FILE);
            if (fclose(in))
                fprintf(stderr, "Can't be closed %s!\n", INP_FILE);
            if (fclose(out))
                fprintf(stderr, "Can't be closed %s!\n", OUT_FILE);
        }
    }
    printf("The file %s was successfully saved as %s\n", INP_FILE, OUT_FILE);
 
    fclose(in);
    fclose(out);
 
#ifdef _DEBUG
    system("pause");
#endif
    return 0;
}

Объяснение кода листинга программы

  1. Включаются необходимые заголовочные файлы для работы с файлами и командной строкой
  2. Определяются макросы ORG_FILE, INP_FILE и OUT_FILE для удобства работы с аргументами командной строки
  3. Инициализируются переменные in и out, которые будут использоваться для работы с файлами
  4. Выводится информация о количестве аргументов и имени функции
  5. Пользователю предлагается ввести имя входного файла и имя выходного файла
  6. Используется функция fopen_s для открытия входного файла. Если файл успешно открыт, выводится сообщение об успешном открытии. В противном случае выводится сообщение об ошибке и программа завершается с кодом 1
  7. Аналогично пункту 6, только для открытия выходного файла
  8. Используется цикл while для чтения входного файла по 4096 байт и записи этих байт во временный буфер buf
  9. Если запись во временный буфер была успешной, вызывается функция fwrite для записи данных из буфера в выходной файл. Если запись не удалась, выводится сообщение об ошибке и закрываются входной и выходной файлы
  10. Проверяется успешность закрытия входного и выходного файлов с помощью функции fclose
  11. Выводится сообщение об успешном сохранении файла
  12. Закрываются входной и выходной файлы
  13. Выводится сообщение о успешном завершении программы
  14. Программа завершается с кодом 0

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 4.167 из 5
Похожие ответы