Работа с файлами и командной строкой - C (СИ)
Формулировка задачи:
Добрый день.
В Си совсем новичок, прошу помощи, хочу и нужно разобраться.
Стоит такая задача: произвести копирование файла (например, in.txt) и назвать out.txt через *arvg[], а затем сделать проверку: если файл не существует, копировать, если существует - удалить и копировать.
Пока написал такой код:
Как результат, просто копирование выполняется, но на следующем выполнении останавливается в первом цикле while.
Visual Studio 2015.
Сразу поясню насчет функций open: fopen отказывается работать, требует fopen_s, но с ней тоже не получилось реализовать. Лишь с помощью функции _sopen_s удалось хоть что-то реализовать (было долго и мучительно).
Буду благодарен за разъяснения.
#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;
}Решение задачи: «Работа с файлами и командной строкой»
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;
}
Объяснение кода листинга программы
- Включаются необходимые заголовочные файлы для работы с файлами и командной строкой
- Определяются макросы ORG_FILE, INP_FILE и OUT_FILE для удобства работы с аргументами командной строки
- Инициализируются переменные in и out, которые будут использоваться для работы с файлами
- Выводится информация о количестве аргументов и имени функции
- Пользователю предлагается ввести имя входного файла и имя выходного файла
- Используется функция fopen_s для открытия входного файла. Если файл успешно открыт, выводится сообщение об успешном открытии. В противном случае выводится сообщение об ошибке и программа завершается с кодом 1
- Аналогично пункту 6, только для открытия выходного файла
- Используется цикл while для чтения входного файла по 4096 байт и записи этих байт во временный буфер buf
- Если запись во временный буфер была успешной, вызывается функция fwrite для записи данных из буфера в выходной файл. Если запись не удалась, выводится сообщение об ошибке и закрываются входной и выходной файлы
- Проверяется успешность закрытия входного и выходного файлов с помощью функции fclose
- Выводится сообщение об успешном сохранении файла
- Закрываются входной и выходной файлы
- Выводится сообщение о успешном завершении программы
- Программа завершается с кодом 0