?
Solved

How do I use malloc and memcpy to put characters in a 2D array?

Posted on 2008-11-11
15
Medium Priority
?
1,041 Views
Last Modified: 2013-11-18
I'm writing a program to split text from a text file into tokens. I am trying to put characters read from the file into a 2D char array called **token. Each "row" in **token is supposed to hold a line of text, and each element in each row is supposed to hold a token from the line.  I've written:

word = (char*) malloc (tokenLength + 1);
memcpy(*token[0], word, tokenLength + 1);

The memcpy statement prompts an error that reads "invalid conversion from 'char' to 'void*' initializing argument 1 of 'void * memcpy(void*, const void*, size_t)' ". How do I use memcpy and avoid this error?
#include <iostream>
#include <fstream>
#include <string.h> 
#include "system_utilities.h"
#include "definitions.h"
 
using namespace std;
 
ifstream file; // create input stream object
 
 
char linetext[256]; // array of characters to hold 255 characters + terminating null char
int length; // variable to hold length of current line of input (num chars)
int pos = 0; // variable to hold position of last character of current input line read by getNextToken
char *word;
 
int errorcode;
 
void printError(int errorcode)
{
   switch ( errorcode )
   {
      case END_OF_FILE:
         cout << "Error: End of file has been reached." << endl;
         break;
      case FILE_NOT_OPENED:
         cout << "Error: File could not be opened." << endl;
         break;
      case TOKEN_NOT_FOUND:
         cout << "Error: Token not found." << endl;
         break;
      default:
         cout << "There is an error." << endl;
   }
}
 
int openInputFile (char fname[])
{
   file.open(fname, ios::in); // what is ios::in for?
   if (file.good())
   {
      cout << fname << " was read successfully" << endl;
      return 0; 
   }
   else
   {
      cout << "file not read successfully" << endl;
      return FILE_NOT_OPENED; 
   }
}
 
int getNextToken(char **token) 
{
   
   int tokenFound = 0; // whether or not a token has been found
   int tokenLength = 0; // length of token
  
   while(tokenFound == 0) // when no token has been found
   {
      if(pos == 0) // if you're at the beginning of a line
      {
         int j;
         for (j = 0; j <256; j++) // set all character array values to NULL
         {
            linetext[j] = '\0';
         }
         file.getline(linetext, 256); // read in a line of text from the file
         length = strlen(linetext); // get the length of the line
      }
      
      // Recognizing single characters and symbols (not quotes)
      int i;
      for(i = pos; i < length && (tokenFound == 0); i++) // loop through the whole line
      {
         if(((linetext[i] != ' ') && (linetext[i] != '\0'))) // if the character is not a space or NULL, or is a symbol
         {
            word = (char*) malloc (tokenLength + 1);
            memcpy(token[0], word, tokenLength + 1);
            cout << "word: " << word << endl;
            tokenLength = i - pos; // length of token
            pos = i + tokenLength; // new pos = next character after i (1 = length of these tokens; not i++ for all tokens)
            tokenFound = 1;
         }
      }
  
      if(pos == length) // if you've reached the end of the line
      {
         pos = 0; // reset pos to 0
         if(file.eof()) // if you've reached the end of the file
         {
            return END_OF_FILE;
         }
      }
   }
   return 0;
}
  
int symbol(char c)
{
   if ((c == '>') || (c == '<') || (c == '/') || (c == '='))
      {
      return 1;
      }
   else
      {
      return 0;
      }
}

Open in new window

0
Comment
Question by:vwps
  • 7
  • 3
  • 2
  • +2
15 Comments
 
LVL 3

Expert Comment

by:SreejithG
ID: 22936893
Please attach .h files too
0
 

Author Comment

by:vwps
ID: 22936903
Sorry about that. Here is system_utilities.h:
int openInputFile(char fname[]); // input file name string, open file and assign to file-level ifstream variable
int getNextToken( char **token ); // finds next token in input file, allocates new space, assigns token to point to new space, copies characters
void printError(int errorcode); // prints appropriate error message
int symbol(char c);

Open in new window

0
 

Author Comment

by:vwps
ID: 22936906
And definitions.h:
#define END_OF_FILE 201 
#define FILE_NOT_OPENED 202 
#define TOKEN_NOT_FOUND 301 
#define MAX_LINE_LENGTH 255 

Open in new window

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 3

Expert Comment

by:SreejithG
ID: 22936938
please provide your main/calling functio function also
0
 

Author Comment

by:vwps
ID: 22936942
main.cpp:
#include <iostream>
#include "system_utilities.h"
#include "definitions.h"
 
using namespace std;
 
int stop;
char **token1;
 
int main() 
{
   openInputFile("symbols.txt");
   while(getNextToken(token1) != END_OF_FILE);
   cout<<"Done";
   cin >> stop;
   return 0;
}

Open in new window

0
 
LVL 17

Expert Comment

by:sweetfa2
ID: 22937345
memcpy( (void*) token[0], word, tokenLength + 1);
0
 

Author Comment

by:vwps
ID: 22937355
Sweetfa2 - thanks for your response! Unfortunately, when I ran that code, it prompted a generic Windows XP error of "Project4-1.exe has encountered a problem and needs to close. We are sorry for the inconvenience." Any thoughts?
0
 
LVL 53

Accepted Solution

by:
Infinity08 earned 1500 total points
ID: 22937906
You need to allocate memory for 'token' before trying to copy data into it.


A few remarks :

>> into a 2D char array called **token.

The 2D array is called 'token' - ** is part of the type, ie. char** or a pointer-to-pointer-to-char.


>> Each "row" in **token is supposed to hold a line of text, and each element in each row is supposed to hold a token from the line.

Currently, the way you defined 'token', it only supports an array of strings (char*). So, that's only one line of text. To support multiple lines of text, you'll need a char*** or pointer-to-pointer-to-pointer-to-char.

Do not forget to properly allocate memory.


Btw, why don't you use the C++ way of allocating memory ? You are using C++, aren't you ?

        http://www.cplusplus.com/doc/tutorial/dynamic.html
        http://www.cplusplus.com/doc/tutorial/pointers.html

I highly recommend reading these tutorials before continuing.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22938643
>>> You need to allocate memory for 'token' before trying to copy data into it.
Not only for token but for each token element as well.

    token = new char*[MAX_TOKEN];
    for (int i = 0;i<MAX_TOKEN ; ++i)
         token[i] = new char[MAX_TOKEN_LENGTH];
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22939217
In C++ use string and vector.

// include the headers for string and vector
#include <string>
#include <vector>
// omit std:: prefix
using namespace std;

// pass line, vecor for tokens and separators, e. g. " ;/,.\()"
int gettokens(const string& str, vector<string> v, string seps)
{
      string s = str + seps[0];  // add separator at end
      int pos1=0;
      int pos2=0;
      while ((pos2 = (int)s.find_first_of(seps, pos1)) != string::npos)
      {
            v.push_back(s.substr(pos1, pos2-pos1));
            pos1 = pos2 + 1;
      }
      return v.size();
}

Note, you call the above for each line. You could take one vector for all lines, or you define a

   vector<vector<string> >  tokensArr;   // note the space between > >

to have one vector for each line.

0
 

Author Comment

by:vwps
ID: 22971645
Thanks a lot!
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22971650
May I ask why you gave a B grade ? That usually means that something was missing in the answer and/or that something is still unclear. If that's the case, then you do not have to close the question, and can just ask for clarification where needed. Do you need something explained further ?
0
 

Author Comment

by:vwps
ID: 22972139
Infinity08 - I'm sorry, I should have been more clear. I read about new and understand that it's more appropriate, but was supposed to use malloc. Can I re-open the question, or is it too late to stop this B from tarnishing your profile?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22972194
>> I read about new and understand that it's more appropriate, but was supposed to use malloc.

No problem :) the concept is the same, except for the syntax (C++ dynamic memory allocation versus C dynamic memory allocation).


>> Can I re-open the question, or is it too late to stop this B from tarnishing your profile?

You can always re-open a question by using the "Request Attention" link if you want to. But don't worry about my profile ;) I just wanted to make sure you got the help you needed, and didn't require any further assistance (which is usualy what a B grade indicates).

Do not hesitate to ask further about this topic if there's still something that you're unsure about.
0
 

Author Comment

by:vwps
ID: 22972500
Infinity08 - Thanks for the explanation!
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

How to remove superseded packages in windows w60 or w61 installation media (.wim) or online system to prevent unnecessary space. w60 means Windows Vista or Windows Server 2008. w61 means Windows 7 or Windows Server 2008 R2. There are various …
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to implement Singleton Design Pattern in Java.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
Suggested Courses
Course of the Month15 days, 7 hours left to enroll

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question