Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > Прога не компилится. В чём ошибки?


Автор: Proger10 26.11.2009, 01:21
Вот такой код (по идее который должен компилиться):
Код

#include <fstream>
#include <iostream>
#include <string>
#include <stdio.h>

using namespace std;

class WavFileForIO
{
/*
     WAV File Specification
     FROM http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
    The canonical WAVE format starts with the RIFF header:
    0         4   ChunkID          Contains the letters "RIFF" in ASCII form
                                   (0x52494646 big-endian form).
    4         4   ChunkSize        36 + SubChunk2Size, or more precisely:
                                   4 + (8 + SubChunk1Size) + (8 + SubChunk2Size)
                                   This is the size of the rest of the chunk 
                                   following this number.  This is the size of the 
                                   entire file in bytes minus 8 bytes for the
                                   two fields not included in this count:
                                   ChunkID and ChunkSize.
    8         4   Format           Contains the letters "WAVE"
                                   (0x57415645 big-endian form).

    The "WAVE" format consists of two subchunks: "fmt " and "data":
    The "fmt " subchunk describes the sound data's format:
    12        4   Subchunk1ID      Contains the letters "fmt "
                                   (0x666d7420 big-endian form).
    16        4   Subchunk1Size    16 for PCM.  This is the size of the
                                   rest of the Subchunk which follows this number.
    20        2   AudioFormat      PCM = 1 (i.e. Linear quantization)
                                   Values other than 1 indicate some 
                                   form of compression.
    22        2   NumChannels      Mono = 1, Stereo = 2, etc.
    24        4   SampleRate       8000, 44100, etc.
    28        4   ByteRate         == SampleRate * NumChannels * BitsPerSample/8
    32        2   BlockAlign       == NumChannels * BitsPerSample/8
                                   The number of bytes for one sample including
                                   all channels. I wonder what happens when
                                   this number isn't an integer?
    34        2   BitsPerSample    8 bits = 8, 16 bits = 16, etc.

    The "data" subchunk contains the size of the data and the actual sound:
    36        4   Subchunk2ID      Contains the letters "data"
                                   (0x64617461 big-endian form).
    40        4   Subchunk2Size    == NumSamples * NumChannels * BitsPerSample/8
                                   This is the number of bytes in the data.
                                   You can also think of this as the size
                                   of the read of the subchunk following this 
                                   number.
    44        *   Data             The actual sound data.
*/


     private:
        char*    myPath;
        int    myChunkSize;
        int    mySubChunk1Size;
         short    myFormat;
        short    myChannels;
        int    mySampleRate;
        int    myByteRate;
        short    myBlockAlign;
        short    myBitsPerSample;
        int    myDataSize;
        
    public:
        // I made this public so that you can toss whatever you want in here
        // maybe a recorded buffer, maybe just whatever you want
        char*    myData;

        // get/set for the Path property
        char* getPath()
        {
            return myPath;
        }
        void setPath(char* newPath)
        {
            myPath = new char[200];
            //strcpy(myPath, newPath);
            myPath = newPath;
        }

        ~WavFileForIO()
        {
            delete myPath;
            myChunkSize = NULL;
            mySubChunk1Size = NULL;
             myFormat = NULL;
            myChannels = NULL;
            mySampleRate = NULL;
            myByteRate = NULL;
            myBlockAlign = NULL;
            myBitsPerSample = NULL;
            myDataSize = NULL;
        }

    // empty constructor
    WavFileForIO()
        {
        myPath = new char[200];
        }

    // constructor takes a wav path
    WavFileForIO(char* tmpPath)
        {
        myPath = new char[200];
        //strcpy(myPath, tmpPath);
        myPath = tmpPath;
        read();
        }

    // read a wav file into this class
    bool read()
    {
        ifstream inFile( myPath, ios::in | ios::binary);

        //printf("Reading wav file...\n"); // for debugging only

        inFile.seekg(4, ios::beg);
        inFile.read( (char*) &myChunkSize, 4 ); // read the ChunkSize

        inFile.seekg(16, ios::beg);
        inFile.read( (char*) &mySubChunk1Size, 4 ); // read the SubChunk1Size

        //inFile.seekg(20, ios::beg);
        inFile.read( (char*) &myFormat, sizeof(short) ); // read the file format.  This should be 1 for PCM

        //inFile.seekg(22, ios::beg);
        inFile.read( (char*) &myChannels, sizeof(short) ); // read the # of channels (1 or 2)

        //inFile.seekg(24, ios::beg);
        inFile.read( (char*) &mySampleRate, sizeof(int) ); // read the samplerate

        //inFile.seekg(28, ios::beg);
        inFile.read( (char*) &myByteRate, sizeof(int) ); // read the byterate

        //inFile.seekg(32, ios::beg);
        inFile.read( (char*) &myBlockAlign, sizeof(short) ); // read the blockalign

        //inFile.seekg(34, ios::beg);
        inFile.read( (char*) &myBitsPerSample, sizeof(short) ); // read the bitspersample

        inFile.seekg(40, ios::beg);
        inFile.read( (char*) &myDataSize, sizeof(int) ); // read the size of the data


        // read the data chunk
        myData = new char[myDataSize];
        inFile.seekg(44, ios::beg);
        inFile.read(myData, myDataSize);

        inFile.close(); // close the input file

        return true; // this should probably be something more descriptive
    }

    // write out the wav file
    bool save()
    {
        fstream myFile (myPath, ios::out | ios::binary);

        // write the wav file per the wav file format
        myFile.seekp (0, ios::beg); 
        myFile.write ("RIFF", 4);
        myFile.write ((char*) &myChunkSize, 4);
        myFile.write ("WAVE", 4);
        myFile.write ("fmt ", 4);
        myFile.write ((char*) &mySubChunk1Size, 4);
        myFile.write ((char*) &myFormat, 2);
        myFile.write ((char*) &myChannels, 2);
        myFile.write ((char*) &mySampleRate, 4);
        myFile.write ((char*) &myByteRate, 4);
        myFile.write ((char*) &myBlockAlign, 2);
        myFile.write ((char*) &myBitsPerSample, 2);
        myFile.write ("data", 4);
        myFile.write ((char*) &myDataSize, 4);
        myFile.write (myData, myDataSize);

        return true;
    }

    // return a printable summary of the wav file
    char *getSummary()
    {
        char *summary = new char[250];
        sprintf(summary, " Format: %d\n Channels: %d\n SampleRate: %d\n ByteRate: %d\n BlockAlign: %d\n BitsPerSample: %d\n DataSize: %d\n", myFormat, myChannels, mySampleRate, myByteRate, myBlockAlign, myBitsPerSample, myDataSize);
        return summary;
    }
};


int main( int argc, char *argv[] )
{
    // make sure that an argument was passed in
    if ( argc != 2 ) 
    {
        cout<<"usage: "<< argv[0] <<" <filename>\n";
        return 0;
    }

    // open the wav file
    char *path = new char[50];
    //strcpy(path, argv[1]);
    path = argv[1];
    WavFileForIO *myWav = new WavFileForIO(path);

    // print a summary of the wav file
    char *summary = myWav->getSummary();
    printf("Summary:\n%s", summary);    

    // write the summary back out
    //strcpy(path, "testout.wav");
    myWav->setPath("testout.wav");
    myWav->save();

    // collect the garbage
    delete summary;
    delete path;
    delete myWav;

    return 0;
}


Но не компилится. smile
Выдавая вот такие ошибки:
Код

01:18:06 waveIO $ gcc wavIO.cpp                                                                                     
wavIO.cpp: In function 'int main(int, char**)':                                                                     
wavIO.cpp:215: warning: deprecated conversion from string constant to 'char*'                                       
/tmp/cclKyqgc.o: In function `__static_initialization_and_destruction_0(int, int)':                                 
wavIO.cpp:(.text+0x23): undefined reference to `std::ios_base::Init::Init()'                                        
wavIO.cpp:(.text+0x28): undefined reference to `std::ios_base::Init::~Init()'                                       
/tmp/cclKyqgc.o: In function `main':                                                                                
wavIO.cpp:(.text+0x77): undefined reference to `std::cout'                                                          
wavIO.cpp:(.text+0x7c): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'                                                                                                                                                        
wavIO.cpp:(.text+0x87): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'                                                                                                                                                        
wavIO.cpp:(.text+0x94): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'                                                                                                                                                        
wavIO.cpp:(.text+0xaa): undefined reference to `operator new[](unsigned long)'                                                                                                     
wavIO.cpp:(.text+0xc7): undefined reference to `operator new(unsigned long)'                                                                                                       
wavIO.cpp:(.text+0x120): undefined reference to `operator delete(void*)'                                                                                                           
wavIO.cpp:(.text+0x129): undefined reference to `operator delete(void*)'                                                                                                           
wavIO.cpp:(.text+0x14e): undefined reference to `operator delete(void*)'                                                                                                           
wavIO.cpp:(.text+0x170): undefined reference to `operator delete(void*)'                                                                                                           
/tmp/cclKyqgc.o: In function `WavFileForIO::setPath(char*)':                                                                                                                       
wavIO.cpp:(.text._ZN12WavFileForIO7setPathEPc[WavFileForIO::setPath(char*)]+0x16): undefined reference to `operator new[](unsigned long)'                                          
/tmp/cclKyqgc.o: In function `WavFileForIO::~WavFileForIO()':                                                                                                                      
wavIO.cpp:(.text._ZN12WavFileForIOD1Ev[WavFileForIO::~WavFileForIO()]+0x14): undefined reference to `operator delete(void*)'                                                       
/tmp/cclKyqgc.o: In function `WavFileForIO::read()':                                                                                                                               
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0x38): undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(char const*, std::_Ios_Openmode)'                                                                                                                                                                   
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0x4e): undefined reference to `std::basic_istream<char, std::char_traits<char> >::seekg(long, std::_Ios_Seekdir)'  
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0x6d): undefined reference to `std::basic_istream<char, std::char_traits<char> >::read(char*, long)'               
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0x83): undefined reference to `std::basic_istream<char, std::char_traits<char> >::seekg(long, std::_Ios_Seekdir)'  
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0xa2): undefined reference to `std::basic_istream<char, std::char_traits<char> >::read(char*, long)'               
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0xc1): undefined reference to `std::basic_istream<char, std::char_traits<char> >::read(char*, long)'               
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0xe0): undefined reference to `std::basic_istream<char, std::char_traits<char> >::read(char*, long)'               
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0xff): undefined reference to `std::basic_istream<char, std::char_traits<char> >::read(char*, long)'               
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0x11e): undefined reference to `std::basic_istream<char, std::char_traits<char> >::read(char*, long)'              
/tmp/cclKyqgc.o:wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0x13d): more undefined references to `std::basic_istream<char, std::char_traits<char> >::read(char*, long)' follow                                                                                                                                                                    
/tmp/cclKyqgc.o: In function `WavFileForIO::read()':                                                                                                                               
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0x172): undefined reference to `std::basic_istream<char, std::char_traits<char> >::seekg(long, std::_Ios_Seekdir)' 
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0x191): undefined reference to `std::basic_istream<char, std::char_traits<char> >::read(char*, long)'              
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0x1a3): undefined reference to `operator new[](unsigned long)'
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0x1c7): undefined reference to `std::basic_istream<char, std::char_traits<char> >::seekg(long, std::_Ios_Seekdir)'
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0x1eb): undefined reference to `std::basic_istream<char, std::char_traits<char> >::read(char*, long)'
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0x1f7): undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::close()'
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0x208): undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()'
wavIO.cpp:(.text._ZN12WavFileForIO4readEv[WavFileForIO::read()]+0x233): undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()'
/tmp/cclKyqgc.o: In function `WavFileForIO::WavFileForIO(char*)':
wavIO.cpp:(.text._ZN12WavFileForIOC1EPc[WavFileForIO::WavFileForIO(char*)]+0x16): undefined reference to `operator new[](unsigned long)'
/tmp/cclKyqgc.o: In function `WavFileForIO::getSummary()':
wavIO.cpp:(.text._ZN12WavFileForIO10getSummaryEv[WavFileForIO::getSummary()]+0x12): undefined reference to `operator new[](unsigned long)'
/tmp/cclKyqgc.o: In function `WavFileForIO::save()':
wavIO.cpp:(.text._ZN12WavFileForIO4saveEv[WavFileForIO::save()]+0x38): undefined reference to `std::basic_fstream<char, std::char_traits<char> >::basic_fstream(char const*, std::_Ios_Openmode)'
wavIO.cpp:(.text._ZN12WavFileForIO4saveEv[WavFileForIO::save()]+0x52): undefined reference to `std::basic_ostream<char, std::char_traits<char> >::seekp(long, std::_Ios_Seekdir)'
wavIO.cpp:(.text._ZN12WavFileForIO4saveEv[WavFileForIO::save()]+0x6c): undefined reference to `std::basic_ostream<char, std::char_traits<char> >::write(char const*, long)'
wavIO.cpp:(.text._ZN12WavFileForIO4saveEv[WavFileForIO::save()]+0x8f): undefined reference to `std::basic_ostream<char, std::char_traits<char> >::write(char const*, long)'
wavIO.cpp:(.text._ZN12WavFileForIO4saveEv[WavFileForIO::save()]+0xa9): undefined reference to `std::basic_ostream<char, std::char_traits<char> >::write(char const*, long)'
wavIO.cpp:(.text._ZN12WavFileForIO4saveEv[WavFileForIO::save()]+0xc3): undefined reference to `std::basic_ostream<char, std::char_traits<char> >::write(char const*, long)'
wavIO.cpp:(.text._ZN12WavFileForIO4saveEv[WavFileForIO::save()]+0xe6): undefined reference to `std::basic_ostream<char, std::char_traits<char> >::write(char const*, long)'
/tmp/cclKyqgc.o:wavIO.cpp:(.text._ZN12WavFileForIO4saveEv[WavFileForIO::save()]+0x109): more undefined references to `std::basic_ostream<char, std::char_traits<char> >::write(char const*, long)' follow
/tmp/cclKyqgc.o: In function `WavFileForIO::save()':
wavIO.cpp:(.text._ZN12WavFileForIO4saveEv[WavFileForIO::save()]+0x22e): undefined reference to `std::basic_fstream<char, std::char_traits<char> >::~basic_fstream()'
wavIO.cpp:(.text._ZN12WavFileForIO4saveEv[WavFileForIO::save()]+0x259): undefined reference to `std::basic_fstream<char, std::char_traits<char> >::~basic_fstream()'
/tmp/cclKyqgc.o:(.eh_frame+0x13): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status

Автор: niXman 26.11.2009, 01:39
Код-то компилится, но не линкуется.
Попробуй так:
Код

g++ wavIO.cpp 

Автор: Proger10 26.11.2009, 04:10
Тьфу блин. Точно. smile

Добавлено через 6 минут и 27 секунд
Единственная трабла в этой проге (для тех кто юзать будет этот исходник), почему-то на последних двух строках:
delete path;
delete myWav;
прога вылетает smile
Код

*** glibc detected *** ./a.out: free(): invalid pointer: 0x000000000040173f ***
======= Backtrace: =========                                                   
/lib/libc.so.6[0x7f5373916488]                                                 
/lib/libc.so.6(cfree+0x6c)[0x7f537391af1c]                                     
./a.out[0x400fb8]                                                              
./a.out[0x400f3e]                                                              
/lib/libc.so.6(__libc_start_main+0xe6)[0x7f53738c0a26]                         
./a.out[0x400d19]                                                              
======= Memory map: ========      

не знаю почему.. перед ней строка "delete summary; " - срабатывает отлично, а эти две не срабатывают. Но если закомментировать, то всё отлично работает. Надеюсь те две строки не существенная потеря smile память ведь освободится самостоятельно после завершения работы проги?

Автор: MAKCim 26.11.2009, 09:48
Proger10
все бы ничего, но

Цитата(Proger10 @  26.11.2009,  04:10 Найти цитируемый пост)
Надеюсь те две строки не существенная потеря smile память ведь освободится самостоятельно после завершения работы проги? 

это плохо пахнет ;)

у вас тут не memory leak, а тупо корявая программа
первое, что сразу видно
Код

 char *path = new char[50];
    //strcpy(path, argv[1]);
    path = argv[1];

а потом вы path удаляете через delete

Автор: nerezus 26.11.2009, 15:23
Цитата

у вас тут не memory leak, а тупо корявая программа
 Имхо тут И то, И другое ;)

Автор: Proger10 26.11.2009, 16:09
А как правильно сделать? Надо было через strcpy?

Автор: MAKCim 26.11.2009, 16:14
Цитата(Proger10 @  26.11.2009,  16:09 Найти цитируемый пост)
А как правильно сделать?

Код

std::string path(argv[1]);

Автор: Proger10 27.11.2009, 22:57
Цитата(MAKCim @ 26.11.2009,  16:14)
Цитата(Proger10 @  26.11.2009,  16:09 Найти цитируемый пост)
А как правильно сделать?

Код

std::string path(argv[1]);

А чего, такой фокус не пройдёт?
Код

#include <iostream>
#include <fstream>

using namespace std;

int main () {

    string str = "test.txt";

    ifstream infile;
    infile.open ( str );

    if ( infile.is_open() ) {
        while ( infile.good() )
            cout << (char) infile.get();
        infile.close();
    } else {
        cout << "Error opening file";
    }
    return 0;
}


Получаю такие ошибки:
Код

ifstream.cpp: In function 'int main()':
ifstream.cpp:11: error: no matching function for call to 'std::basic_ifstream<char, std::char_traits<char> >::open(std::string&)'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/include/g++-v4/fstream:495: note: candidates are: void std::basic_ifstream<_CharT, _Traits>::open(const 
char*, std::_Ios_Openmode) [with _CharT = char, _Traits = std::char_traits<char>]


А в таких случаях как поступают обычно? smile

Автор: Proger10 28.11.2009, 00:18
Опаньки. Понял в чём фишка. Меняем:
Код

infile.open ( str.c_str() );

И всё отлично работает!

Добавлено через 7 минут и 15 секунд
Ещё пара вопросов..

1. Если я в функцию хочу передать ссылку на объект типа std::string мне не нужно употреблять символ "*"?
Т.е.:
bool func( string str );
или же так? 
bool func( string* str );

Походу первый вариант правильный? Потому что string это объект, а объект уже является сам по себе ссылкой, поэтому нет необходимости указывать ссылку.. Но так в яве, а в с++ не уверен smile

2. Нужно ли очищать как-то очищать память после std::string str("asdf") ? Или сама очистится?

Автор: andrew_121 28.11.2009, 01:50
Код

bool func( const string& str );

Автор: comcon1 3.12.2009, 17:31
Цитата(Proger10 @  28.11.2009,  00:18 Найти цитируемый пост)
Походу первый вариант правильный? Потому что string это объект, а объект уже является сам по себе ссылкой, поэтому нет необходимости указывать ссылку.. Но так в яве, а в с++ не уверен 


И правильно не уверен. В java если ты пишешь:

Код

public void get(String arg) { // lalal }
//....
s = new String("sfe");
cl.get(s);


..., то //lala работает со ссылкой на s.

В С++ в таком же коде, во время входа в функцию запустится конструктор копирования (сам по себе):
Код

arg = new String(s);


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)