Menu

strlen problem in bloodshed v4.9.8.7

2004-04-10
2012-09-26
  • Nobody/Anonymous

    I have included the code that I am compiling and that I believe has an issue.  The strlen function is returning the lenght + 2 for anything that I pass it.  I have compiled the exact same code under Microsoft Visual C++ version 6 and it works fine.
    I am using Windows XP Professional Service Pak 1, Bloodshed compiler version 4.9.8.7, the computer is Intel Based with 512MB Memory.
    The compile log is as follows:
    Compiler: Default compiler
    Building Makefile: "C:\DOCUME~1\sbotkin\MYDOCU~1\PROGRA~1\C__~1\Homework\direct\Makefile.win"
    Executing  make...
    make.exe -f "C:\DOCUME~1\sbotkin\MYDOCU~1\PROGRA~1\C__~1\Homework\direct\Makefile.win" all
    make.exe: Nothing to be done for `all'.

    Execution terminated
    Compilation successful

    The source code in question is:
    #include <iostream>
    #include <fstream>
    #include <cstring>
    #include <stdlib.h>

    using namespace std;

    int main(int argc, char *argv[])
    {
        int i, pos2;
        char s[100];
       
        fstream f( "textfile.txt", ios::in|ios::out|ios::trunc);
        // write two lines to the file
        f << "This is line no 1" << endl;
        pos2 = f.tellp();  //Line 2 begins here
        f << "Line number 2" << endl;
        // Write out the file
        f.seekp(0);
        while ( f.getline( s, 100 ))
            cout << "|" << s << "|" << endl;
       
        f.clear(); // Necessary after EOF
        // Change the first word to stars
        f.seekp(0);
        f >> s;
        f.seekp(0);
       
        i = strlen(s);
                                             ///
        cout << "strlen(s) " << i << endl;   /// problem here strlen returns 6 should be 4
                                             /// the string it is reading is "This is line no 1"
                                             /// strlen should terminate after the first word "This"
                                             /// return a value of 4 but it doesn't
        for (int i=1; i <= strlen(s); i++)
            f.put('*');
        f.flush();

        // Write an X in the middle of the 2nd line
        f.seekp(pos2);
        f.getline(s, 100);
        f.seekp(pos2+strlen(s)/2);
        f << 'X';
        f.seekp(0);
        cout << f.rdbuf();
        f.close();
      system("PAUSE");   
      return 0;
    }

    If anyone has a suggestion other than rewrite strlen to work correctly, or just subtract 2 from it I would like to hear from them.  Would love to know where the problem really resides....  besides in my program...

    Thanks,
    Steve sbotkin@charter.net

     
    • Wayne Keen

      Wayne Keen - 2004-04-10

      Well, I tried this little experimental program I stole off the internet - yes, it is Friday, and I am lazy:

      /* strlen example */
      #include <stdio.h>
      #include <string.h>
      #include <stdlib.h>

      int main ()
      {
        char szInput[256];
        printf ("Enter a sentence: ");
        gets (szInput);
        printf ("Sentence entered is %u characters long\n",strlen(szInput));
        system("pause");
        return 0;
      }

      I compiled it as a C program.  It seems to indicate that strlen is working correctly here.  I am using Dev 4.9.8.7 / Windows XP Home - Now I will look closer at your program.

      :-)

      Wayne

       
    • Wayne Keen

      Wayne Keen - 2004-04-10

      OK, now, something struck me.  No, not my wife.
      Your print of S occurs several steps before you do your strlen operation.  So I said to myself, Wayne, you gotta quit talking to yourself", then I put a print of S in right before your strlen print.

      i = strlen(s);
      ///
      cout << "wayne ----- " << s << endl;
      cout << "strlen(s) " << i << endl; /// problem here strlen returns 6 should be 4

      You know, good old fashioned non-debugger debugging.  Guess what I got.  It told me s is

      ThThis

      So, S is in fact 6 characters long!

      So, there is something wrong with what you are doing to s, nothing wrong with strlen

      Wayne

       
    • Wayne Keen

      Wayne Keen - 2004-04-10

      Here is the whole modified program.  I am tired and don't want to delve into what is going wrong in your code with respect to s, because I would likely get frustrated at my stupidity.  Maybe after some shut-eye...

      "I have compiled the exact same code under Microsoft Visual C++ version 6"

      Statements like this seldom are helpful.  First, compilers do differ.  VS6 is decidely pre-standard, separated by more than 5 years from GCC-3.2.  The fact that code compiles on one compiler does not mean it is right, or wrong.

      There is also an air of "my code is right, there is something wrong with your compiler" that is likely to piss the people off you are trying to get to help you. 

      Wayne

       
    • Nobody/Anonymous

      Wayne,
      Really appreciate you looking at this...
      I have added the additional lines of code below:

          f.clear(); // Necessary after EOF
          s[0] = '\0';
          // Change the first word to stars
          cout << "s before second f.seekp(0) " << "|" << s << "|" << endl;
          f.seekp(0);
          f >> s;
          cout << "s before second f.seekp(0) " << "|" << s << "|" << endl;
          f.seekp(0);
          cout << s << endl;
          i = my_strlen( s );

      It looks like the f.seekp(0) is not getting the correct info / position from the file....
      not sure where to look now...  

       
      • Wayne Keen

        Wayne Keen - 2004-04-10

        I will look at it in the morning, when my IQ may rise out of the single digits.

        Or maybe one of the smarter guys here will enlighten us both....there are a number of folks here that are MUCH sharper than me...

        Wayne

         
    • Wayne Keen

      Wayne Keen - 2004-04-10

      #include <iostream>
      #include <fstream>
      #include <cstring>
      #include <stdlib.h>

      using namespace std;

      int main(int argc, char *argv[])
      {
      int i, pos2;
      char s[100];

      fstream f( "textfile.txt", ios::in|ios::out|ios::trunc);
      // write two lines to the file
      f << "This is line no 1" << endl;
      pos2 = f.tellp(); //Line 2 begins here
      f << "Line number 2" << endl;
      // Write out the file
      f.seekp(0);
      while ( f.getline( s, 100 ))
      cout << "|" << s << "|" << endl;

      f.clear(); // Necessary after EOF
      // Change the first word to stars
      f.seekp(0);
      f >> s;
      f.seekp(0);

      i = strlen(s);
      ///
      cout << "wayne you bozo ----- " << s << endl;
      cout << "strlen(s) " << i << endl; /// problem here strlen returns 6 should be 4
      /// the string it is reading is "This is line no 1"
      /// strlen should terminate after the first word "This"
      /// return a value of 4 but it doesn't
      for (int i=1; i <= strlen(s); i++)
      f.put('*');
      f.flush();

      // Write an X in the middle of the 2nd line
      f.seekp(pos2);
      f.getline(s, 100);
      f.seekp(pos2+strlen(s)/2);
      f << 'X';
      f.seekp(0);
      cout << f.rdbuf();
      f.close();
      system("PAUSE");
      return 0;
      }

       
    • Nobody/Anonymous

      I have now taken the same code as I first posted and compiled and run it on a Solaris system 2.6 & 2.9 both with GCC 3.3.2 and 3.2 and the program runs to completion correctly.

      scarecrow{}318$ g++ -o direct -v direct.cpp
      Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/3.2/specs
      Configured with: ../configure --with-as=/usr/ccs/bin/as --with-ld=/usr/ccs/bin/ld --disable-nls
      Thread model: posix
      gcc version 3.2
      /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/3.2/cc1plus -v -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=0 -D__GXX_ABI_VERSION=102 -Dsparc -Dsun -Dunix -D__svr4__ -D__SVR4 -D__PRAGMA_REDEFINE_EXTNAME -D__sparc__ -D__sun__ -D__unix__ -D__svr4__ -D__SVR4 -D__PRAGMA_REDEFINE_EXTNAME -D__sparc -D__sun -D__unix -Asystem=unix -Asystem=svr4 -D__NO_INLINE__ -D__STDC_HOSTED__=1 -D_XOPEN_SOURCE=500 -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE=1 -D__EXTENSIONS__ -D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc direct.cpp -D__GNUG__=3 -D__DEPRECATED -D__EXCEPTIONS -quiet -dumpbase direct.cpp -version -o /var/tmp//cc0Zrwc8.s
      GNU CPP version 3.2 (cpplib) (sparc ELF)
      GNU C++ version 3.2 (sparc-sun-solaris2.6)
              compiled by GNU C version 3.2.
      ignoring nonexistent directory "NONE/include"
      #include "..." search starts here:
      #include <...> search starts here:
      /usr/local/include/c++/3.2
      /usr/local/include/c++/3.2/sparc-sun-solaris2.6
      /usr/local/include/c++/3.2/backward
      /usr/local/include
      /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/3.2/include
      /usr/local/sparc-sun-solaris2.6/include
      /usr/include
      End of search list.
      /usr/ccs/bin/as -V -Qy -s -o /var/tmp//ccpgbeN7.o /var/tmp//cc0Zrwc8.s
      /usr/ccs/bin/as: WorkShop Compilers 4.X dev 18 Sep 1996
      /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/3.2/collect2 -V -Y P,/usr/ccs/lib:/usr/lib -Qy -o direct /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/3.2/crt1.o /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/3.2/crti.o /usr/ccs/lib/values-Xa.o /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/3.2/crtbegin.o -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.6/3.2 -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.6/3.2/../../../../sparc-sun-solaris2.6/lib -L/usr/ccs/bin -L/usr/ccs/lib -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.6/3.2/../../.. /var/tmp//ccpgbeN7.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc -lc /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/3.2/crtend.o /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/3.2/crtn.o
      ld: Software Generation Utilities - Solaris-ELF (4.0)

      scarecrow{}320$ ./direct
      |This is line no 1|
      |Line number 2|
      s before second f.seekp(0) ||
      s before second f.seekp(0) |This|
      This
      my_strlen(s) 4
      **** is line no 1
      Line nXmber 2

      According to the bloodshed website the current build is based off of the GCC 3.2 version, so I tried the different versions to see if it responded differently.
      If anyone can help explain why I am getting differences between these and the bloodshed version I would greatly appreciate the help.  I am not very good at using the debugger once it goes off into the libraries...
      Thanks,
      Steve

       
      • Nobody/Anonymous

        I have found a reference to someone else who was having a problem and posted a problem here with seekp, I now think that it is the seekp function that is not working correctly....

        The previous post was :

        seekp problems  
        2003-06-12 07:09

        The person who posted then seems to have had the same problem as what I am having with additional characters being added in front of the string that is expected....

        If anyone can help with this I would really appreciate it...
        Thanks,
        Steve

         
    • Wayne Keen

      Wayne Keen - 2004-04-11

      Looking at some documentation:

      http://www.cplusplus.com/ref/iostream/ostream/seekp.html

      and running the example seems to indicate that seekp is operating correctly. 

      Wayne

       
    • Nobody/Anonymous

      Wayne,
      I am not sure why you have pointed me to an example of writing using ofstream instead of fstream.  The example that you have tried and hence declared that seekp is operating correctly is correct for that piece of code using ofstream, not direct access using fstream.  Do you have some code that is using fstream that we can try?  The program that I have used is an example straight out of a book that should work.  As I have stated earlier I have tried the exact same code on many different systems, using a few different gcc versions and it works just fine.  It just doesn't work with the bloodshed compiler.  I appologize if I sound a little rattled but as I stated earlier when I try to debug this and it goes off into the library I get lost...  I do appreciate your looking at this since no one else has even offered a suggestion..  So thanks...  I just am not sure where to go at this point..
      Thanks,
      Steve

       
    • Nobody/Anonymous

      haven't looked at the code fully (or compliled it), but try setting the file type to binary or text. This will ensure that your file type is consistent on different machines/compilers. Then re-do testing.

       
    • Nobody/Anonymous

      I don't know who you are but thank you.  I have changed the following line of code from:
      fstream f( "textfile.txt", ios::in|ios::out|ios::trunc);
      to the following:
      fstream f( "textfile.txt", ios::binary|ios::in|ios::out|ios::trunc);
      and the code now works like it does on my Sparc Systems using gcc 3.2 and 3.3.2 without the binary flag...   Thanks, this was driving me nuts trying to figure out why this one would not work and all of the others would.... 
      It would be nice to find out why you have to add the binary option to the fstream for this to work correctly in Bloodshed but not in any of the others...
      Thanks Again....
      Steve

       
      • joe

        joe - 2004-04-12

        >>It would be nice to find out why you have to add the binary option to the fstream for this to work correctly in Bloodshed but not in any of the others...<<

        Not an expert, and I didn't look closely at the problem code...however, if using binary fixed the problem, then you likely encountered an issue where on a DOS machine '/n' is represented by a 2-byte sequence versus a 1-byte sequence on most other systems.

         
    • Wayne Keen

      Wayne Keen - 2004-04-12

      One qualification, it does not appear to be a "Bloodshed" issue.

      I ran your original code under separate stand-alone version of MinGW/MSYS (gcc version 3.2.3) and got the same result.

      $ ./a
      |This is line no 1|
      |Line number 2|
      wayne you bozo ----- ThThis
      strlen(s) 6
      Press any key to continue . . .

      ******is is line no X 1
      Line number 2

      I ran the original code in Cygwin (GCC version 3.3.1), and got a better result:

      $ ./a
      |This is line no 1|
      |Line number 2|
      wayne you bozo ----- This
      strlen(s) 4
      **** is line no 1
      Line nXmber 2
      PAUSE: not found

      Wayne

       
    • Nobody/Anonymous

      Wanye,
      I think you are right that it is a mingw problem...  Since that is the base that is used in bloodshed, I was wrong in saying it was a bloodshed problem but that happens when you lack the experience of identifing the problem, which I have... lack of experience that is..   I do appreciate the help on here to find out how to get around it, but would like to know is there someone that I should tell or inform that the mingw version of the gcc compiler is not functioning as the other versions do on other platforms...  Thanks again all for you help...
      Steve

       
    • aditsu

      aditsu - 2004-04-13

      > It would be nice to find out why you have to add the binary option to the fstream for this to work correctly in Bloodshed but not in any of the others...

      files in C and C++ use text-mode I/O by default (i.e. if you don't specify access mode explicitly);
      on most linux and unix platforms, that is no different from binary mode, because the line ends are marked with a single EOL character
      but on other platforms, most notably Windows, line ends have different markers which are translated to/from EOL in text mode and are left alone in binary mode

      Adrian

       
    • Anonymous

      Anonymous - 2004-04-14

      In windows it probably changes to \r\n for the EOL return in text but not in binary where it probably uses only \n.
      *hmmm....* I should look into this.

       
    • Nobody/Anonymous

      after a bit testing I think that its not a good to set the eof flag on an in- and out- put stream.

      rndiablo

       

Log in to post a comment.

MongoDB Logo MongoDB