Heyy, back again.

another function I need to write checks to see if the characters of a String state code(such as PA) are in uppercase and if they aren't I need to make them uppercase. (so has to check for stuff like pa, Pa, pA and fix it)

the state code HAS to be a String as per prof assignment. (it's in the private of the header file)

I tried converting the string into a character array but I got the error error C2440: 'initializing' : cannot convert from 'class String' to 'char'

I am using tstring and not string as again per prof assignment.

if I could convert it to string I know I can just use if statements to check case and then just shift the char on the ascii chart if the case is wrong, but I don't know how to do this with a String.


so how can I convert the string into 2 chars without saving the data as a char array originally and then convert it back to String?

OR

is there a way of doing this without converting it to char?


prob obvious what I'm doing wrong but again, our class didn't actually get this far I'm just using experience from other languages.(mostly alice and blitz basic)

String PatientDemographicInformation::getPatientState( )
{
	char state[2] = {patientState};

	String fixState;

	if (state[1] >= 97 || state [1] <= 122)
	{
		state[1] -= 32;
	}
	else if (state[1] >= 65 || state [1] <= 90)
	{
		state[1] = state[1];
	}
	else
	{
		cerr << "invalid char";
		exit(9);
	}

	if (state[2] >= 97 || state [2] <= 122)
	{
		state[2] -= 32;
	}
	else if (state[1] >= 65 || state [1] <= 90)
	{
		state[2] = state[2];
	}
	else
	{
		cerr << "invalid char";
		exit(9);
	}

	fixState = state[1] + state[2];
	return fixState;
}

Edited 6 Years Ago by viziroth: n/a

It's hard to help you without knowing more about this String class. If it's even remotely reasonable, you should be able to do this:

for (int i = 0; i < s.length(); i++)
  s[i] = toupper(s[i]);

>char state[2] = {patientState};
This is probably wrong. I suspect patientState is a String object.

>if (state[1] >= 97 || state [1] <= 122)
Even assuming the assumption that these values correctly represent 'a'-'z' and the reader is expected to know that, magic numbers are bad. You can use character literals to the same effect and the code will be vastly more readable. Or you can use the functions from <cctype> and avoid this kind of grunt work entirely.

>state[1] -= 32;
This isn't guaranteed to work. Not all character sets are compatible.

>exit(9);
There has to be a better way to respond to an invalid character than terminating the application. Especially from a utility class. :icon_rolleyes:

>fixState = state[1] + state[2];
Array indices start at 0 in C++. You're accessing the array out of bounds.

Hi .. i'm not sure about this but try it.

#include <string>
#include <iostream>
using namespace std;

int main (int argc,char* argv[])
  {
    argc=1;
    string  str=argv[argc];
    char holds[100];
    char* s=const_cast<char*>(str.c_str());
    for (unsigned int i=0;i<str.length();i++)
      {
        holds[i]=*s;
        *s++;
      }
  }

>argc=1;
>string str=argv[argc];

Wow. That's actually pretty impressive for a Bug of Ignorance™.

>char holds[100];
Erm, how do you know str.size() is less than 100?

>char* s=const_cast<char*>(str.c_str());
What a fantastically horrible idea! c_str returns a pointer to const char for a reason, and that reason isn't so you can cast it away and modify the memory anyway. :icon_rolleyes:

>for (unsigned int i=0;i<str.length();i++)
I hope I'm not the only one who sees a failure to terminate the holds string with a null character.

:) hey .. look honey .The guy asked how to split a string in chars. Holds is not supposed to be used as a string but to extract characters from it.Bet it works .. why don't you post something better ?

viziroth, I'm quite confused as to what you are asking here. I believe your question can be simplified. Do point out what you want to ask and make it clear. Thanks.

I guess I just need to split a string into chars.

and it's in a header file so I don't need int main....

Also, the toupper thing that Narue mentioned...

s is the string object? or is it a newly declared object?

do I need to include another header or is that a built in function? a

Ok let me try rephrasing it.

I am making a header file. One of the attributes in the private sector is a string patientState, it will be declared in the constructor, I need to write a function to make sure each letter is capitalized.


I was using the numbers because we're using an ascii chart in class.
As for the exit(9) my partner added that in.

Edited 6 Years Ago by viziroth: n/a

#include <string>
#include <iostream>
#include <cctype>
using namespace std;

string to_upper(string);

int main ()
  {
    string s="string_literal";    
    string uppered=to_upper(s);
    cout << uppered;
  }

string to_upper(string str)
  {         
    char *parser=const_cast<char*>(str.c_str()); // this points to the beggining of the string
    string uppercased;
    for (unsigned int x=0;x<str.length();x++)   // while parsing the string
      {
        uppercased+=toupper(*parser); // add another char        
        *parser++;  // point to next char of string        
      }
    return uppercased;
  }

Just integrate the function to_upper in your header file.

Edited 6 Years Ago by Nick Evan: Fixed code-tags

#include <string>
#include <iostream>
#include <cctype>
using namespace std;

string to_upper(string);

int main ()
  {
    string s="string_literal";    
    string uppered=to_upper(s);
    cout << uppered;
  }

string to_upper(string str)
  {         
    char *parser=const_cast<char*>(str.c_str()); // this points to the beggining of the string
    string uppercased;
    for (unsigned int x=0;x<str.length();x++)   // while parsing the string
      {
        uppercased+=toupper(*parser); // add another char        
        *parser++;  // point to next char of string        
      }
    return uppercased;
  }

>The guy asked how to split a string in chars.
No, he asked how to change the case of characters in a string. He also failed to describe how the non-standard string class being used works. If it's mutable, extracting the characters is completely unnecessary. If it's immutable then it makes more sense, but if it's immutable I would rather expect a robust collection of member functions and friends to handle this kind of grunt work.

>Holds is not supposed to be used as a string but to extract characters from it.
If it's not supposed to be a string, then I concede that point.

>Bet it works
Bet I can break it without changing the code. What you posted exhibits undefined behavior and supremely stupid programming practices.

>why don't you post something better ?
That's easy enough:

#include <cctype>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

std::string uppercase(const std::string& s)
{
    typedef std::vector<char>::iterator iter_t;

    // Assume std::string is immutable for fun
    std::vector<char> conv(s.begin(), s.end());

    for (iter_t it = conv.begin(); it != conv.end(); ++it)
    {
        *it = std::toupper((unsigned char)*it);
    }

    return std::string(conv.begin(), conv.end());
}

int main(int argc, char *argv[])
{
    if (argc < 1)
    {
        std::cerr<<"usage: $prog <string>\n";
        return EXIT_FAILURE;
    }

    std::string before(argv[1]);
    std::string after = uppercase(before);

    std::cout<<"Before: "<< before <<'\n';
    std::cout<<"After:  "<< after <<'\n';

    return EXIT_SUCCESS;
}

Though it's only "better" in terms of correcting your broken code. It doesn't help the OP at all because we still don't know jack about the String class he's using. Note that in the OP's code, String is capitalized. That's important.

>char *parser=const_cast<char*>(str.c_str());
You learned nothing, I see. Too stubborn to admit that just because it works for you doesn't mean it's correct?

Edited 6 Years Ago by Narue: n/a

I didn't use vectors because i thought it was too much for him already.I aimed for comprehensible code.By the way i know that casting the const away is brute force so stop showing off.:*

>Ok let me try rephrasing it.
I'll do the same. Post your String class. You won't get any solid answers until we know how it works.

>I didn't use vectors because i thought it was too much for him already
Then you have two choices:

  1. Make a huge array and hope the string isn't longer.
  2. Dynamically allocate an array.

The former is risky and wasteful, the latter is more complicated than using vectors. Personally, I think the standard library should be introduced as early as possible to avoid the overwhelming lower level stuff.

>By the way i know that casting the const away is brute force
It's not brute force, it's just plain unsafe. On closer inspection it's probably okay in this case since you don't actually modify the string, but still a horrible example to set if you're trying to teach something other than how not to write C++.

>so stop showing off
Pointing out problems in your code is showing off? Get over yourself. You're making matters worse by jumping to conclusions and posting bad code that isn't even usable by the OP.

:) Well .. the += is overloaded in class string so this should settle things down regarding the use of arrays in this case. Secondly it's just simple code for a course assignment so you don't have to jump on my head. And third .. i think i love you :* Keep posting

Comments
You're quickly turning into a creepy stalker. Watch yourself.
Fail.
This question has already been answered. Start a new discussion instead.