nixp.ru v3.0

18 октября 2017,
среда,
14:25:29 MSK

DevOps с компанией «Флант»
anonymous написал 5 апреля 2005 года в 20:22 (1786 просмотров) Ведет себя неопределенно; открыл 1814 темы в форуме, оставил 5575 комментариев на сайте.

При чтении данных из файла в строку buf в неё печатаются ещё какие-то символы, которых нет в файле:

Исходная строка в файле: akjdlhfajfdhkjfhalksdjfahlskdfj

Строка buf: akjdlhfajfdhkjfhalksdjfahlskdfj ИЬ@

Вот кусок текста проги:

char *cp;

ifstream in(argv[1],ios::in | ios::binary);

if (!in){

cerr<<"Cannot open «<<argv[1]<<endl;

exit(1);}

do {

if (in.eof()) cp = '\0\′;

else cp=in.get();

i++;}

while (!in.eof());

in.close();

Как сделать так, чтобы buf содержала только оригинальную строку? (Копировать нужно именно посимвольно, чтобы читать файл любой длины).

metal

Предлагаю оптимизировать цикл:

while (!in.eof())

{

cp=in.get();

i++;

}

cp = '\0\′;

и попробовать читать файл как текстовый.

Под cp выделена память?

Longobard

а обнулять выделенную память кто будет?

sas
Alex777
При чтении данных из файла в строку buf в неё печатаются ещё какие-то символы, которых нет в файле:

Исходная строка в файле: akjdlhfajfdhkjfhalksdjfahlskdfj

Строка buf: akjdlhfajfdhkjfhalksdjfahlskdfj ИЬ@

Вот кусок текста проги:

char *cp;

ifstream in(argv[1],ios::in | ios::binary);

if (!in){

cerr<<"Cannot open «<<argv[1]<<endl;

exit(1);}

do {

if (in.eof()) cp = '\0\′;

else cp=in.get();

i++;}

while (!in.eof());

in.close();

Как сделать так, чтобы buf содержала только оригинальную строку? (Копировать нужно именно посимвольно, чтобы читать файл любой длины).

Вообще раз уж это C++, то лучше что-то вроде (чтение всего файла в строку разом)

ifstream f( "test.txt" );
        if ( f.good ) {
           f.unsetf( ios_base::skipws );
      
           string buf( istream_iterator( f ), istream_iterator() );
           cout << "Got [" << buf << "]\n";
       }

Хотя посимвольное чтение с точки зрения производительности не очень…

Кроме того я не понял Вашу фразу о чтении файла любой длины…

Обычно, если файл очень большой и его не хотят грузить в буфер используют mmap или чтение в буфер фиксированной длины (getline метод).

Кстати проблема Вашего кода в том, что Вы не проверяете состояние потока

после get

string buf;
    int c = f.get();
    while ( !f.eof() ) {
         buf.push_back( static_cast( c ) );
         c = f.get();
    }

Будет работать.

Удачи

— sas

Longobard

Да проще всего сделать так:

void * buff;
int fd = open( path.c_str(), O_RDONLY );
buff = mmap( 0, FileLength, PROT_READ, MAP_PRIVATE, fd, 0 );
string some_str = (string)buff;

man mmap ;)

anonymous

Попробовал вариант:

ifstream f( «test.txt» );

if ( f.good ) {

f.unsetf( ios_base::skipws );

string buf( istream_iterator( f ), istream_iterator() );

cout << «Got [" << buf << "]\n»;

}

Выдаются такие ошибки:

Member function must be called or its address taken

Qualifier ‘ios_base’ is not a class or namespace name

Function call missing ) //по поводу двух параметров buf ?

Undefined symbol ‘istream_iterator’

Expression syntax

Может быть нужно подключить какие-нибудь библиотеки?( у меня подключены iostream.h, cstring.h, fstream.h, ctype.h, stdlib.h, а в программировании я новичок)

Попробовал и вариант:

string buf;

int c = f.get();

while ( !f.eof() ) {

buf.push_back( static_cast( c ) );

c = f.get();

}

Выдаётся следующая ошибка: ‘push_back’ is not a member of ‘string’

Вариант Longobard’a ещё не пробовал.

P.S Программирую я под Windows, так как в институте Linux’a нет.

anonymous

Попробовал вариант:

ifstream f( «test.txt» );

if ( f.good ) {

f.unsetf( ios_base::skipws );

string buf( istream_iterator( f ), istream_iterator() );

cout << «Got [" << buf << "]\n»;

}

Выдаются такие ошибки:

Member function must be called or its address taken

Qualifier ‘ios_base’ is not a class or namespace name

Function call missing ) //по поводу двух параметров buf ?

Undefined symbol ‘istream_iterator’

Expression syntax

Может быть нужно подключить какие-нибудь библиотеки?( у меня подключены iostream.h, cstring.h, fstream.h, ctype.h, stdlib.h, а в программировании я новичок)

Попробовал и вариант:

string buf;

int c = f.get();

while ( !f.eof() ) {

buf.push_back( static_cast( c ) );

c = f.get();

}

Выдаётся следующая ошибка: ‘push_back’ is not a member of ‘string’

Вариант Longobard’a ещё не пробовал.

P.S Программирую я под Windows, так как в институте Linux’a нет.

decvar

В помойке есть примеры. В примерах это есть.

sas
Alex777
Попробовал вариант:

ifstream f( «test.txt» );

if ( f.good ) {

f.unsetf( ios_base::skipws );

string buf( istream_iterator( f ), istream_iterator() );

cout << «Got [" << buf << "]\n»;

}

Выдаются такие ошибки:

Member function must be called or its address taken

Qualifier ‘ios_base’ is not a class or namespace name

Function call missing ) //по поводу двух параметров buf ?

Undefined symbol ‘istream_iterator’

Expression syntax

Может быть нужно подключить какие-нибудь библиотеки?( у меня подключены iostream.h, cstring.h, fstream.h, ctype.h, stdlib.h, а в программировании я новичок)

Попробовал и вариант:

string buf;

int c = f.get();

while ( !f.eof() ) {

buf.push_back( static_cast( c ) );

c = f.get();

}

Выдаётся следующая ошибка: ‘push_back’ is not a member of ‘string’

Вариант Longobard’a ещё не пробовал.

P.S Программирую я под Windows, так как в институте Linux’a нет.

У Вас наверное старый компилятор. Дело в том, что современный С++ использует заголовочные файлы (не библиотеки) названия которых не заканчиваются на *.h Кроме того современный basic_string включает в себя (по стандарту) push_back метод.

Код с mmap у Вас не пойдет на Windows.

#include 
#include 
#include 
#include 
using namespace std;
int main()
{
      ifstream f( "test.txt" );
      string buf;
      int c = f.get();
      while ( !f.eof() ) {
            buf.push_back( static_cast( c ) );
            c = f.get();
      }      
      cout << "Got [" << buf << "]\n";
      
      return 0;
}



#include 
#include 
#include 
#include 
using namespace std;
int main()
{
      ifstream f( "test.txt" );
      if ( f.good() ) {
            f.unsetf( ios_base::skipws );
            istream_iterator begin( f );
            istream_iterator end;
            string buf( begin, end );
            
            cout << "Got [" << buf << "]\n";
      }      
        return 0;
}



#include 
#include 
#include 
#include 
#include 
using namespace std;
int main()
{
      string buf;
      ifstream f( "test.txt" );
        if ( f.good() ) {
            f.unsetf( ios_base::skipws );
      
            copy(
                istream_iterator( f ),
                istream_iterator(),
                back_inserter( buf )
            );
      
            cout << "Got [" << buf << "]\n";
        }
        return 0;
}

Должен компилироваться и работать на всех системах с современными космпиляторами С++

Я его только что прогнал на Linux и на Mac OS X

g++ -Wall -o fr test.cc

gcc version 3.3

Если у Вас нет современного компилятора, то советую скачать cygwin. Он в себя включает, насколько я знаю, нормалбный gcc

myst

Лучше — MinGW.

aspolyakov

Подскажите а с юникс aio_* что-то подобное есть? оболчки для этих апи итд? Тщетно пытался с ними работать((

myst

Ты сам понял, что сказал? Если ты имел ввиду:

«Есть ли под UNIX реалицазии POSIX API асинхронного ввода/вывода (aio_*)?»

то — да.

aspolyakov

я имел в виду класс реализующий чтение по строкам или как там еще может понадобится на основе асинхронных апи. Вобще может либы и оболочки есть, чтобы ошибки самому не проверять итд