Like Tree1Likes

How do I create a filename with multiple variable types

This is a discussion on How do I create a filename with multiple variable types within the C++ Programming forums, part of the General Programming Boards category; I have a set of text files where the titles coorespond to the date they were written (such as 01-31-12, ...

  1. #1
    Registered User
    Join Date
    Dec 2008
    Posts
    38

    How do I create a filename with multiple variable types

    I have a set of text files where the titles coorespond to the date they were written (such as 01-31-12, where 01 is january, 31 is the thrity first, and 12 is the year). In my C++ code, I have an array with different variables allocating different numbers to different blocks in the array to check different files for a comparison to a keyword. Problem is, the dashes are a char, and the numbers are, well, numbers. Is there an easy workaround for this problem, or do I have to restructure my filenames?

    I'm teaching myself programming, so please don't presume a college level education.

  2. #2
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,239
    sscanf() ought to work:

    Code:
    #include <cstdio>
    
    char *filenameExample = "01-31-12";
    int month, day, year;
    
    std::sscanf(filenameExample, "%d-%d-%d", &month, &day, &year);
    (For those about to complain that I used a C function, have your C++ version ready for comparison)
    stahta01 likes this.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    Registered User
    Join Date
    Dec 2008
    Posts
    38
    Good enough. Thanks.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,602
    Quote Originally Posted by brewbuck
    (For those about to complain that I used a C function, have your C++ version ready for comparison)
    Not too difficult:
    Code:
    int month, day, year;
    std::stringstream ss("01-31-12");
    ss >> month >> literal('-') >> day >> literal('-') >> year;
    // or:
    ss >> month >> '-' >> day >> '-' >> year;
    if only we had continued working on getting an input matching manipulator standardised, or getting the formatted read to ignore literals added to the standard I/O streams
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,239
    [hangs head in shame]
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  6. #6
    Registered User
    Join Date
    Oct 2006
    Posts
    2,351
    care to explain the head hanging? aside from trying to read directly into literals, I see nothing wrong with laserlight's example.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,602
    We were working on a project to allow one or the other to work as part of the C++ standard library, but brewbuck decided that he did not have the time to see it through.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    Kolkata@India
    Posts
    2,498
    Quote Originally Posted by laserlight View Post
    Not too difficult:
    Code:
    int month, day, year;
    std::stringstream ss("01-31-12");
    ss >> month >> literal('-') >> day >> literal('-') >> year;
    // or:
    ss >> month >> '-' >> day >> '-' >> year;
    if only we had continued working on getting an input matching manipulator standardised, or getting the formatted read to ignore literals added to the standard I/O streams
    How can the second one be implemented ?
    (The first one, I think, can just be a templated function, taking and returning a reference to the istream involved, plucking out the argument passed into it. Am I right ?)
    Manasij Mukherjee | gcc-4.8.2 @Arch Linux
    Slow and Steady wins the race... if and only if :
    1.None of the other participants are fast and steady.
    2.The fast and unsteady suddenly falls asleep while running !



  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,602
    Quote Originally Posted by manasij7479
    How can the second one be implemented ?
    By overloading operator>> in the std namespace (for argument dependent lookup) to have two parameters: a non-const reference to std::basic_istream and a const reference to char.

    Quote Originally Posted by manasij7479
    (The first one, I think, can just be a templated function, taking and returning a reference to the istream involved, plucking out the argument passed into it. Am I right ?)
    No, it is not as simple as that because the function call does not involve the istream. One way out is for the function call to create an object that has operator>> overloaded for basic_istream. This object then contains the argument provided as an argument to the input manipulator, and then its operator>> uses that value to perform the input manipulation.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    Kolkata@India
    Posts
    2,498
    Quote Originally Posted by laserlight View Post
    No, it is not as simple as that because the function call does not involve the istream. One way out is for the function call to create an object that has operator>> overloaded for basic_istream. This object then contains the argument provided as an argument to the input manipulator, and then its operator>> uses that value to perform the input manipulation.
    After simplifying a little and abstracting the work of the >> in the () operator, here is my try:
    Code:
    template<typename T>
    class literal
    {
        T t;
    public:
        literal(T t_):t(t_){};
        istream& operator()(istream& is)
        {
            T temp;
            is>>temp;
            if(temp!=t)is.setstate(ios_base::failbit);
            return is;
        }
    };
    template<typename T>
    istream& operator>>(istream& is,literal<T> lt)
    {
        return lt(is);
    }
    Example use:
    Code:
    int main()
    {
        int x,y;
        cin>>x>>literal<char>('+')>>y;
        cout<<x<<endl<<y;
        return 0;
    }
    Doe this fall short anywhere ?
    Last edited by manasij7479; 02-11-2012 at 01:21 PM.
    Manasij Mukherjee | gcc-4.8.2 @Arch Linux
    Slow and Steady wins the race... if and only if :
    1.None of the other participants are fast and steady.
    2.The fast and unsteady suddenly falls asleep while running !



  11. #11
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,538
    Quote Originally Posted by laserlight View Post
    By overloading operator>> in the std namespace (for argument dependent lookup) to have two parameters: a non-const reference to std::basic_istream and a const reference to char.
    Hrm. That causes an ambiguous overload for me: the compiler cannot decide between std::stringstream::operator >> (int&) and std::operator > (std::stringstream&, const char&).
    Last edited by Elysia; 02-11-2012 at 03:24 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    4,217
    O_o

    This:

    Code:
    namespace std
    {
        istream & operator >>
        (
            istream & fLHS
          , const char & fRHS
        );
    }
    not this:

    Code:
    namespace std
    {
        stringstream & operator >>
        (
            stringstream & fLHS
          , const char & fRHS
        );
    }
    Soma

  13. #13
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,538
    Just for the sake of it, I made an attempt at implementing the first method:

    Code:
    #include <sstream>
    #include <iostream>
    #include <assert.h>
    
    template<typename StreamT>
    class XLiteral
    {
    public:
    	XLiteral(char c): m_c(c) {}
    	void SetStream(std::basic_istream<StreamT>& stream) { m_stream = &stream; }
    	template<typename T> XLiteral& operator >> (T& rhs) { assert(m_stream); *m_stream >> rhs; return *this; }
    	char GetChar() const { return m_c; }
    
    protected:
    	std::basic_istream<StreamT>* m_stream;
    	char m_c;
    };
    
    template<typename StreamT>
    XLiteral<StreamT> & operator >> (std::basic_istream<StreamT>& lhs, XLiteral<StreamT>& rhs) 
    {
    	char tmp;
    	lhs >> tmp;
    	assert(tmp == rhs.GetChar());
    	rhs.SetStream(lhs);
    	return rhs;
    }
    
    template<typename StreamT>
    XLiteral<StreamT> literal(StreamT c) { return XLiteral<StreamT>(c); }
    
    int main()
    {
    	int month, day, year;
    	std::stringstream ss("31-01-12");
    	ss >> day >> literal('-') >> month >> literal('-') >> year;
    }
    (Also took the liberty to fix the date format.)

    It compiles and works fine under Visual Studio, but not with Comeau. Dunno why. I am probably missing something trivial.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Registered User manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    Kolkata@India
    Posts
    2,498
    Quote Originally Posted by Elysia View Post
    Dunno why. I am probably missing something trivial.
    a.cpp: In function ‘int main()’:
    a.cpp:36:26: error: no match for ‘operator>>’ in ‘ss.std::basic_stringstream<char>::<anonymous>.std ::basic_iostream<char>::<anonymous>.std::basic_ist ream<_CharT, _Traits>:perator>> [with _CharT = char, _Traits = std::char_traits<char>]((* & day)) >> literal [with StreamT = char](45)’
    What does that <anonymous > mean, though ?

    (Also, why are you templating it w.r.t to the stream type ? ... shoudn't choosing the base class... i.e istream or basic_istream be enough ?)
    Manasij Mukherjee | gcc-4.8.2 @Arch Linux
    Slow and Steady wins the race... if and only if :
    1.None of the other participants are fast and steady.
    2.The fast and unsteady suddenly falls asleep while running !



  15. #15
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,538
    It complains there is no match for operator >> (basic_istream<T>, XLiteral). But the WHY is what I don't understand.
    basic_istream is a template class and istream is a typedef for basic_istream<char>. This way, you can use either char or wchar_t.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Page 1 of 3 123 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Overloading a variable with multiple data types
    By CPlus in forum C++ Programming
    Replies: 18
    Last Post: 02-13-2010, 03:25 PM
  2. Creating multiple files with string as filename
    By jmayer in forum C++ Programming
    Replies: 2
    Last Post: 01-25-2008, 08:55 AM
  3. Using a variable for a filename
    By Unlockitall in forum C++ Programming
    Replies: 4
    Last Post: 12-15-2007, 09:41 AM
  4. I/O--Using a variable as a filename
    By jedo in forum C++ Programming
    Replies: 7
    Last Post: 09-06-2005, 10:57 AM
  5. Variable filename
    By Azmeos in forum C++ Programming
    Replies: 7
    Last Post: 06-09-2003, 02:42 PM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21