?
Solved

Questions about strings or (char arrays) and classes

Posted on 2000-01-23
12
Medium Priority
?
287 Views
Last Modified: 2010-04-02
I have several questions regarding the same thing - strings.
I am trying to read in at most 128 characters, null terminated. In fact, the string may not even contain anything, so it would be 128 null chars.
I have been able to do this and print it out to STDOUT. I want to assign this value (or a pointer) to an array in my class.
The last thing I want to do is see if the string contains anything, and if so print it out to a file.

Here is my code:

test.h
 class Test {
  private:
  char StreetName[129];
 };

test.cpp
 test::GetData{
  char StreetNameVal[129];
  inFile.read(StreetNameVal, 128);
// Next line or some kind of pointer assign?
  strcpy(StreetName,StreetNameVal);
 }

 test::PrintData{
  if(StreetName) {
   XmlFile << "\t<StreetName>" << StreetName << "</StreetName>" << endl ;
  } else {
   XmlFile << "\t<StreetName/>" << endl ;
  }

By the way I am new to C++ (but you knew that) so be nice. :)

Cliff
0
Comment
Question by:cliff_m
12 Comments
 
LVL 3

Expert Comment

by:akalmani
ID: 2380405
Hey cliff !!
 What's the problem ???
0
 

Author Comment

by:cliff_m
ID: 2380409
It doesn't work when I try to assign it to my class(private variable) and so far I have only been able to print hexadecimal character sequence to my xml file(obviously a reference of some sort).
What I am looking for, I guess, is the right way to do it, passing by reference instead of by value, and being able to dereference it to print out to a file.

Cliff
0
 
LVL 14

Expert Comment

by:AlexVirochovsky
ID: 2380416
>>strcpy(StreetName,StreetNameVal); error
If string can contain 0x00, you code must be:
  memcpy(StreetName,StreetNameVal,128);
becouse strcpy copies only untill 1-st
0x00 (and 0, of course).


 
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 

Author Comment

by:cliff_m
ID: 2380427
I forgot to mention that the statement:
 strcpy(StreetName,StreetNameVal);
crashes the application. So does:
 memcpy(StreetName,StreetNameVal,128);
but I can cout << StreetName and get either a blank line or the text in that field.

BTW I don't need to read in the x00, I was just saying that it won't always be there to read in.

Cliff
0
 
LVL 7

Expert Comment

by:KangaRoo
ID: 2380740
Should you be reading exactly 128 chars (always) or at most 128 chars? The Q contradicts itself.
0
 
LVL 4

Expert Comment

by:inpras
ID: 2380781
Hi  cliff_m
test::GetData{
char StreetNameVal[129];
streetNameVal[129] = '\0';
inFile.read(StreetNameVal, 128);
strcpy(StreetName,StreetNameVal);
}

this I think will not give U assertion

any way what does this statement do?
XmlFile << "\t<StreetName>" << StreetName << "</StreetName>" << endl ;

0
 

Expert Comment

by:Toronado
ID: 2381162
Hi cliff_m,

Can't you use this :

test::GetData (void)
{
 StreetName[0] = '\0';
 inFile.read (StreetName, 128);
}
Now you skip the copy at all.

About the test.
Use strlen (StreetName) > 0 to check if
their is anything in the array.

The test
  if(StreetName) { ...
 
will alway be true because StreetName is a value <> 0

Regards,
 Toronado.
0
 
LVL 22

Expert Comment

by:nietod
ID: 2381181
>> inFile.read(StreetNameVal, 128);
works if the string is always stored as exactly 128 characters.  Is that the case?  Like if the string is short, oul it be padded to 128 characters with NUL characters?  That woudl be unusual.  Also you have room to store 129 characters, that is there is room in your array for 1 more.  Do you neeed to be placing a NUL in the last position, like might this string sometimes be 128 characters that are not NUL, so you have to put a NUL in in the 129th?

I think there are probably two problems here, but can't tell for sure.
I.e a missing NUL and the assumption that the string is always the same length.

>> What I am looking for, I guess, is the right way to do it,
>> passing by reference instead of by value, and being able
>> to dereference it to print out to a file.
Passing what by reference?  I don't see anything that is a candidate for that.

Perhaps you need to consider using a string class?  They can be passed around extremely efficiently.

>> I forgot to mention that the statement:
>> strcpy(StreetName,StreetNameVal);
>>  crashes the application.
That will happen if the source, StreetNameVal, is not properly terminated with a NUL, as I suggested above this might be the case.

>> So does:
>> memcpy(StreetName,StreetNameVal,128);
That is very surprising.  Are you sure?

>> I can cout << StreetName and get either a blank line
>> or the text in that field.
"cout << " with a charater array only works if the character arrays is properly NUL terminated.  I suspect yours is not.

>> I don't need to read in the x00
Then you should consider using the getline() function.  it reads up to 1 line, regardless of its length.
0
 
LVL 22

Expert Comment

by:nietod
ID: 2381187
consider

include <strig>
using namespace std;

class Test
{
private:
  string StreetName;  // stores any length string,
                              // passes it around efficiently.
};

//                  test.cpp
Test::GetData
{
   geline(inFile,StreetName);  // reads whole line
                           // regardless of length.
}

Test::PrintData
{
   if(StreetName.length())
   {
      XmlFile << "\t<StreetName>" << StreetName << "</StreetName>"       << endl ;
   }
   else
   {
      XmlFile << "\t<StreetName/>" << endl ;
   }
}
0
 

Author Comment

by:cliff_m
ID: 2381728
About the data, string is always padded to 128 characters and will always contain a null so I was in error declaring a char array of 129(128+1). It should be 128(127+1).

I will look at proposed solutions and get back to all of you.

Cliff
0
 

Accepted Solution

by:
ymeng earned 1200 total points
ID: 2382281
Cliff,

Since you are new to C++, I'll try to stay with your original code as close as possible. I'll point out the errs in your code and add comments using //**
The extra class members are only added for testing purpose. You should be able to cut/paste the code and run it.

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

//** const is the C++ style
const int BUFFER_LEN = 128;

//test.h
class Test {
public:
 Test();
 void PrintData();

private:  
  void GetData();
  char StreetName[BUFFER_LEN];
  ifstream inFile;
  ofstream XmlFile;
 };

//test.cpp

Test::Test()
{
  inFile.open("test.txt");

  if (inFile.is_open() == false)
        cout << "get problem";

  XmlFile.open("out.txt");
  GetData();
}
 
void Test::GetData()
{
  //** no need for it // char StreetNameVal[BUFFER_LEN ];
  //** null the string,
  //** read() will not null terminate your str

      memset(StreetName, 0, BUFFER_LEN);
      inFile.read(StreetName, BUFFER_LEN);
 
// Next line or some kind of pointer assign?

//** next line is dangerous, read() func
//** may not null terminate StreetNameVal
//  strcpy(StreetName,StreetNameVal);
 }

void Test::PrintData(){
 //** next test is wrong:
 //** StreetName is the address of the
 //** of the variable. It will always
 //** be non-zero, therefor always true
 // if(StreetName) {

 if (strlen(StreetName)) {
   XmlFile << "\t<StreetName>" << StreetName << "</StreetName>" << endl ;
  } else {
   XmlFile << "\t<StreetName/>" << endl ;
  }
}

void main()
{
  Test t;
 
  t.PrintData();

}
0
 

Author Comment

by:cliff_m
ID: 2382607
I appreciate all of the help. The main issue that I was dealing with was not terminating my char arrays. I am giving the points to ymeng because of his excellent answer.

Thank you,

Cliff
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

592 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