Форум программистов, компьютерный форум CyberForum.ru

копирование - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.73
Игорь с++
 Аватар для Игорь с++
429 / 452 / 15
Регистрация: 26.01.2011
Сообщений: 2,029
24.05.2011, 09:28     копирование #1
господа програмисты как скопировать информацию из одного .txt в другой?
Если можно посмотреть не большой,примитивный исходник.
Заранее всем большое спасибо!!!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.05.2011, 09:28     копирование
Посмотрите здесь:

C++ Копирование массивов
Копирование указателя С++ C++
C++ Копирование
Копирование строк C++
Копирование строк C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
24.05.2011, 09:33     копирование #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
// функция копирования потока in в поток out; потоки должны быть открыты
void filecopy(ifstream &in, ofstream &out)
{ char ch;
  while(in.get(ch))        // читать все символы, в том числе пробельные
    out.put(ch); 
}
int main()
{    ifstream instrm ("c:/textfiles/oonumber.txt");
     ofstream outstrm("c:/textfiles/oonumber.new");
     if (instrm) filecopy(instrm, outstrm); // копирование файлов
 return EXIT_SUCCESS;
}
Функция копирования может быть и такой:
C++
1
2
3
4
5
void filecopy(ifstream &in, ofstream &out)
{ char ch;
  while(in.read(&ch, 1))    // читать все символы, в том числе пробельные
    out.write(&ch,1); 
}
И еще один вариант функции копирования:
C++
1
2
3
4
5
6
7
void filecopy(ifstream &in, ofstream &out)
{ char ch = in.get(); 
  while(!in.eof()) 
  { out.put(ch);
    ch = in.get();          // читать все символы, в том числе пробельные
  }
}
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
24.05.2011, 13:52     копирование #3
C++
1
2
3
4
5
6
7
8
#include <cstdio>
int main(){
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    for(char c;!feof(stdin);printf("%c",c))
        scanf("%c",&c);
    return 0;
}
asics
Freelance
Эксперт C++
 Аватар для asics
2838 / 1775 / 144
Регистрация: 09.09.2010
Сообщений: 3,842
24.05.2011, 14:09     копирование #4
Еще вариант:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <fstream>
#include <string>
#include <iterator>
 
void cp(std::ifstream &f, std::ofstream &t){
  std::string s( (std::istreambuf_iterator<char>(f)),
                  std::istreambuf_iterator<char>() );
  t << s;
}
 
int main(){
  std::ifstream ifs("1.txt");//From
  std::ofstream ofs("2.txt");//To
  if(!ifs || !ofs){
    std::cerr << "ERROR";
    return 1;
  }
  cp(ifs, ofs);
  return 0;
}
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.05.2011, 15:26     копирование #5
Копировать из файла по одному символу - очень неэффективно.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <fstream>
 
int main(int argc, char* argv[])
{
    if(argc != 3)
    {
    std::cerr << "Usage: " << *argv << " INPUT_FILE OUTPUT_FILE" << std::endl;
    return 1;
    }
 
    std::ifstream ifs(argv[1]);
    std::ofstream ofs(argv[2]);
 
    if(!ifs || !ofs)
    {
    std::cerr << "Can't open file(s)" << std::endl;
    return 1;
    }
 
    ofs << ifs.rdbuf();
 
    ifs.close();
    ofs.close();
    
    return 0;
}
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
24.05.2011, 16:34     копирование #6
Показанные мной варианты копируют как текстовые, ТАК И БИНАРНЫЕ ФАЙЛЫ. Более того, при открытии файла в режиме дозаписи эта же функция допишет в конец существующего файла.
Еще одно достоинство моих вариантов - ПРОСТОТА и краткость!
Насчет неэффективности. Не забывайте, что ввод-вывод буферизован. Фактически на устройство запись осуществляет ОС, причем всего буфера сразу. А в прикладной проге осуществляется обмен с буфером. Так что в данном случае достоинства перевешивают недостатки, из которых указан только один - якобы неэффективность.
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.05.2011, 17:33     копирование #7
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Показанные мной варианты копируют как текстовые, ТАК И БИНАРНЫЕ ФАЙЛЫ.
Мой тоже. Ну и что?
Пример
Код
[nameless@desktop cpp]$ ls && make && ./sample sample sample2 && chmod -v u+x sample2 && ./sample2 main.cc out.txt && cat out.txt
main.cc  Makefile
g++ -c -Wall -g  main.cc
g++ -o sample  main.o
права доступа «sample2» изменены на 0764 (rwxrw-r--)
#include <iostream>
#include <fstream>

int main(int argc, char* argv[])
{
    if(argc != 3)
    {
	std::cerr << "Usage: " << *argv << " INPUT_FILE OUTPUT_FILE" << std::endl;
	return 1;
    }

    std::ifstream ifs(argv[1]);
    std::ofstream ofs(argv[2]);

    if(!ifs || !ofs)
    {
	std::cerr << "Can't open file(s)" << std::endl;
	return 1;
    }

    ofs << ifs.rdbuf();

    ifs.close();
    ofs.close();
    
    return 0;
}
[nameless@desktop cpp]$


Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Более того, при открытии файла в режиме дозаписи эта же функция допишет в конец существующего файла.
То же самое у меня:
Код
[nameless@desktop cpp]$ ls && make && ./sample main.cc out.txt && ./sample Makefile out.txt && cat out.txt
main.cc  Makefile
g++ -c -Wall -g  main.cc
g++ -o sample  main.o
#include <iostream>
#include <fstream>

int main(int argc, char* argv[])
{
    if(argc != 3)
    {
	std::cerr << "Usage: " << *argv << " INPUT_FILE OUTPUT_FILE" << std::endl;
	return 1;
    }

    std::ifstream ifs(argv[1]);
    std::ofstream ofs(argv[2], std::ios_base::app);

    if(!ifs || !ofs)
    {
	std::cerr << "Can't open file(s)" << std::endl;
	return 1;
    }

    ofs << ifs.rdbuf();

    ifs.close();
    ofs.close();
    
    return 0;
}
TARGET=sample
SOURCES=$(wildcard *.cc)
BINARIES=$(SOURCES:.cc=.o)

CXX=g++
CXXFLAGS=-Wall -g # -std=c++0x
LDFLAGS=

RM=rm -fv

all: $(TARGET)

$(TARGET): $(BINARIES)
	$(CXX) -o $@ $(LDFLAGS) $^

$(BINARIES): $(SOURCES)
	$(CXX) -c $(CXXFLAGS) $^

clean:
	$(RM) $(BINARIES) $(TARGET) *~

.PHONY: all clean
[nameless@desktop cpp]$
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Еще одно достоинство моих вариантов - ПРОСТОТА и краткость!
Насчет простоты не соглашусь. У меня вон вообще полезная работа выполняется в строке 21 - запись буфера (т.е. содержимого) входного файла в выходной. Одной командой. Все очень просто и понятно.
Аргумент насчет краткости вообще не в тему.

Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Насчет неэффективности. Не забывайте, что ввод-вывод буферизован. Фактически на устройство запись осуществляет ОС, причем всего буфера сразу. А в прикладной проге осуществляется обмен с буфером. Так что в данном случае достоинства перевешивают недостатки, из которых указан только один - якобы неэффективность.
Сделаем простой тест на рандомном файле размера ~50 MB:
Код
[nameless@desktop cpp]$ dd if=/dev/urandom ibs=1024k count=50 of=random.txt && ll -h
50+0 записей считано
102400+0 записей написано
 скопировано 52428800 байт (52 MB), 8,24631 c, 6,4 MB/c
итого 51M
-rw-rw-r--. 1 nameless nameless 432 Май 24 22:27 main.cc
-rw-rw-r--. 1 nameless nameless 304 Май 13 00:26 Makefile
-rw-rw-r--. 1 nameless nameless 50M Май 25 00:02 random.txt
Твоя программа:
Код
[nameless@desktop cpp]$ cat main.cc && make && time ./sample random.txt random_copy1.txt
#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

// функция копирования потока in в поток out; потоки должны быть открыты
void filecopy(ifstream &in, ofstream &out)
{
    char ch;
    while(in.get(ch))        // читать все символы, в том числе пробельные
	out.put(ch); 
}

int main(int argc, char* argv[])
{
    if(argc != 3)
	return EXIT_FAILURE;
    
    ifstream instrm (argv[1]);
    ofstream outstrm(argv[2]);
    
    if (instrm)
	filecopy(instrm, outstrm); // копирование файлов
    else
	return EXIT_FAILURE;
    
    return EXIT_SUCCESS;
}
g++ -c -Wall -g  main.cc
g++ -o sample  main.o

real	0m1.866s
user	0m1.781s
sys	0m0.073s
Моя программа:
Код
[nameless@desktop cpp]$ mv main.cc.bak main.cc && make clean
rm -fv main.o sample *~
удалён «main.o»
удалён «sample»
[nameless@desktop cpp]$ cat main.cc && make && time ./sample random.txt random_copy2.txt
#include <iostream>
#include <fstream>

int main(int argc, char* argv[])
{
    if(argc != 3)
    {
	std::cerr << "Usage: " << *argv << " INPUT_FILE OUTPUT_FILE" << std::endl;
	return 1;
    }

    std::ifstream ifs(argv[1]);
    std::ofstream ofs(argv[2]);

    if(!ifs || !ofs)
    {
	std::cerr << "Can't open file(s)" << std::endl;
	return 1;
    }

    ofs << ifs.rdbuf();

    ifs.close();
    ofs.close();
    
    return 0;
}
g++ -c -Wall -g  main.cc
g++ -o sample  main.o

real	0m0.072s
user	0m0.003s
sys	0m0.068s
Разница заметна невооруженным взглядом.
Для проверки, оба результирующих файла идентичны исходному:
Код
[nameless@desktop cpp]$ diff random.txt random_copy1.txt -s
Файлы random.txt и random_copy1.txt идентичны
[nameless@desktop cpp]$ diff random.txt random_copy2.txt -s
Файлы random.txt и random_copy2.txt идентичны
[nameless@desktop cpp]$
Можно еще раз: какие есть достоинства у твоей программы (которых нет у моей), которые превышают "якобы неэффективность"?
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
24.05.2011, 17:39     копирование #8
Вообще по простоте и краткости выигрывает мой вариант=)
А посимвольно/построчно существенной роли не играет, интеловский компилятор с ключами на максимальную оптимизацию к примеру скорость выполнения обоих программ примерно уравняет.
Да и по памяти ваша программа проигрывает=)
Игорь с++
 Аватар для Игорь с++
429 / 452 / 15
Регистрация: 26.01.2011
Сообщений: 2,029
24.05.2011, 17:45  [ТС]     копирование #9
Спасибо всем огромное,я получил более чем изчерпавующие ответы на свой вопрос.
Всем спасибо!!!
Nameless One
24.05.2011, 17:47
  #10

Не по теме:

diagon, а можно узнать, с какими ключиками надо тогда собирать? Оптимизациями никогда не занимался, просто интересно

diagon
24.05.2011, 17:52
  #11

Не по теме:

-fast, либо более безопасная -o3

Nameless One
24.05.2011, 17:59
  #12

Не по теме:

На g++ ни -O3, ни -Ofast ничего не изменили...

diagon
24.05.2011, 18:02
  #13

Не по теме:

у g++ нету -fast (и не -Ofast xD)
Вообще тут есть про это более подробно, там же время выполнения программ указано... интел в полтора раза быстрее g++ работает

kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
24.05.2011, 18:06     копирование #14
А чё никто не упоминает про API-функцию CopyFile?

http://vsokovikov.narod.ru/New_MSDN_...n_copyfile.htm
Игорь с++
 Аватар для Игорь с++
429 / 452 / 15
Регистрация: 26.01.2011
Сообщений: 2,029
24.05.2011, 18:12  [ТС]     копирование #15
господа а почему в этом коде
C++
1
2
3
4
5
6
7
8
#include <cstdio>
int main(){
    freopen("1.txt","r",stdin);
    freopen("2.txt","a",stdout);
    for(char c;!feof(stdin);printf("%c",c))
        scanf("%c",&c);
    return 0;
}
постоянно дописывается в конце сымый последний символ,он же лишний!!!
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
24.05.2011, 18:18     копирование #16
Странно о_О
Видимо лишняя итерация происходит
Хотя у меня работает...
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
diagon@shadeware:~$ cat ./main.cpp
#include <cstdio>
int main(){
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    for(char c;!feof(stdin);printf("%c",c))
        scanf("%c",&c);
    return 0;
}
diagon@shadeware:~$ g++ main.cpp
diagon@shadeware:~$ cat ./input.txt
12345
diagon@shadeware:~$ ./a.out
diagon@shadeware:~$ cat ./output.txt
12345
Игорь с++
 Аватар для Игорь с++
429 / 452 / 15
Регистрация: 26.01.2011
Сообщений: 2,029
24.05.2011, 18:21  [ТС]     копирование #17
именно в вашем коде всё норм,но я в файле output перенаправил поток на до запись,а не перезапись,и происходит вот так как я писал
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
24.05.2011, 21:42     копирование #18
Цитата Сообщение от Nameless One Посмотреть сообщение
Можно еще раз: какие есть достоинства у твоей программы (которых нет у моей), которые превышают "якобы неэффективность"?
Я не стал приводить вариант с буфером той по причине, что спрашивал НОВИЧОК...
Ваша простота - для эксперта. Моя - для новичка...
Это как Страуструп написал две книжки: одну (сначала) для экспертов, в вторую (недавно) - для новичков...

А разница в цифрах объясняется разницей в количестве вызовов методов, очевидно...

Добавлено через 1 минуту
Цитата Сообщение от kravam Посмотреть сообщение
А чё никто не упоминает про API-функцию CopyFile?

http://vsokovikov.narod.ru/New_MSDN_...n_copyfile.htm
Потому как это - Windows-специфик. А речь идет о С++ для начинающих
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.05.2011, 22:03     копирование
Еще ссылки по теме:

копирование C++
C++ Копирование массивов
Копирование указателей C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
24.05.2011, 22:03     копирование #19
Никто не запрещал начинающим не бояться всего и вся
C++
1
2
3
4
5
#include <windows.h>
int main(){   
 CopyFile ("main.cpp", "main_.cpp", true);
 return 0;
}
Эта херь, два из параметров которой- имена, а третий указание чё делать при наличии файла- приёмника. Думаю, разобрался бы. Тем более, ссыль русскоязычная.
Yandex
Объявления
24.05.2011, 22:03     копирование
Ответ Создать тему
Опции темы

Текущее время: 00:21. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru