[Solved] C++ errors for C code


First of all, you need to decide whether you’re writing C or C++. C does not support classes, and you should not use C-style strings, I/O, and memory management routines in C++ code. Mixing elements of the two languages is a recipe for heartburn.

C and C++ are completely different languages that happen to share a lot of syntax and semantics, and a well-written C program doesn’t look or behave much like a well-written C++ program.

Now that the obligatory rant is out of the way, your two main type errors are as follows:

while(gets(*(myLines+s)) != ' ') 

gets (which you should never never never use in either C or C++ for any reason) returns a value of type char *, but the character literal ' ' has type char (in C++; in C, it has type int). char and char * are different, incompatible types, and you cannot do comparisons between them.

Your other type error is

 myWord[s] = strdup(myLines); 

myLines is an array of char *, which in this context “decays” to type char **. strdup expects an argument of type char *, hence the error. You need to pass a specific element of the array to strdup:

myWord[s] = strdup( myLines[s] );

Additionally, you cannot compare C-style strings using the == or != operators; you must use a library function like strcmp, such as

while ( strcmp( buffer, " " ) != 0 )
  ...

Note that we’re doing the comparison against the string literal " " instead of the character literal ' '.

If you want to write C code, then you need to change assem from a class to a struct, and move the function delcarations outside of the struct definition, and pass the struct type as an argument to the functions:

/**
 * .h file
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct assem
{
    char myString[101]; 
    char *myLines[20]; 
    int counter;                            
};

int readFile(FILE *FileToBeRead, struct assem *item );       
int firstCheck( struct assem item );
void printFile( struct assem item);                       

Then you need to remove the assem:: prefix from your function definitions and use the struct assem argument:

int readFile(FILE *file, struct assem *item) 
{
  size_t i = 0;
  item->counter = 0;

  /**
   * get the number of array elements in item->myLines
   */
  size_t maxLines = sizeof item->myLines / sizeof *item->myLines;

  while( i < maxLines && fgets( item->myString, sizeof item->myString, file ) ) 
  {
    item->myLines[i] = strdup(item->myString);
    i++;
    item->counter++;
  }   

  return 0;
}

void printFile( struct assem item ) 
{
  printf("\n");
  for(int s = 0; s < item.counter; s++)
  {
      printf("%s\n", item.myLines[s])); // use subscript notation; it's 
                                        // easier on the eyes
  }
  printf("\n");
}

int firstCheck( struct assem item )                 
{
  char *myWord [7] = {NULL};

  for(int s = 0; s < item.counter; s++)        
  {
    /**
     * In your original code, you were overwriting the myLines array,
     * which contained what you read from the input file; I'm not sure
     * you want to do that here, so I'm using myString instead.
     */
    while( strcmp( fgets( item.myString, sizeof item.myString, stdin ), " " ) != 0 ) 
    {                                                        
      myWord[s] = strdup(item.myString); 
    }           
  }

  /**
   * At this point, you've dynamically allocated memory for the elements
   * of the myWords array, but you aren't using the array outside of this
   * function and you aren't freeing that memory when you're done, meaning
   * you have a memory leak.
   *
   * If they myWords array doesn't need to exist outside of this function,
   * then you need to free each element before exiting.
   */
  return 0;       
}

and then save all that as a .c file and compile it with a C compiler such as gcc.

If you want to write C++ code, then you should use the fstream, string, and vector types instead of FILE and array types, and you should take advantage of C++ features like the std::copy function template and stream iterators:

#include <string>
#include <vector>
#include <fstream>
#include <iterator>
#include <algorithm>

class assem
{
  public:

    // don't need the temporary myString buffer

    std::vector< std::string > myLines;

    // since vectors know how big they are, you don't need a separate
    // counter attribute.

    int readFile( std::istream& fileToBeRead );
    int firstCheck( );
    int printFile( );
};

int assem::readFile( std::istream& fileToBeRead )
{
  /**
   * Use the copy function template with a stream iterator to 
   * read the input file into your myLines vector
   */
  std::copy( 
    std::istream_iterator<std::string>( fileToBeRead ), // start 
    std::istream_iterator<std::string>( ),              // end
    back_inserter( myLines )                            // destination
  );
  return 0;
}

void assem::printFile( )
{
  /**
   * Use the same copy method to write each string in the myLines vector
   * to standard output (again using a stream iterator), separated by 
   * newlines.  
   */
  std::cout << std::endl;  // write the leading newline
  std::copy(
    myLines.begin(),                                          // start
    myLines.end(),                                            // end
    std::ostream_iterator< std::string >( std::cout, "\n" )   // destination
  );
}

int assem::checkFirst( )
{
  std::vector< std::string > myWords;

  for ( std::vector::size_type s = 0; s < myLines.size(); s++ )
    std::cin >> myWords;

  return 0;
}

int main( void )
{
  std::ifstream fileToBeRead( "myfile.txt" ); // or whatever its name is
  if ( fileToBeRead )
  {
    assem myAssem;
    myAssem.readFile( fileToBeRead );
    fileToBeRead.close();
    ...
  }
  ...
}

then save that as a .cpp file and compile it with a C++ compiler, such as g++. Notice that with the C++ code you don’t need to muck with strdup or worry about fixed array sizes, making the code a bit cleaner.

There are other issues with some of the program logic (what are the return values of readFile and checkFirst going to be used for, and is 0 the right value for that purpose), but this should at least get you on the right track.

Hopefully.

EDIT

I realized the logic in the C++ checkFirst routine is not a correct translation of your original code. I know I said you shouldn’t mix C-style strings and I/O in C++ code, but sometimes you don’t have a choice. Here’s something that should be similar:

#include <cstring>         // C++ header file for C-style string routines
... 
char buf[N];               // N is large enough for your input plus 0 terminator
while ( std::cin.get( buf, sizeof buf ) && std::strcmp( buf, " " ) != 0 )
  myWords.push_back ( std::string( buf ) );

1

solved C++ errors for C code