• Advertisement
Sign in to follow this  

Accessing individual characters in an array of strings

This topic is 4173 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Im writing sort of a text encryption program in which im storing individual words of a text string in an array. Each element in the array contains individuals words. The size of the array is allocated dynamically at run time. I've gotten the words counted and stored in the individual elements in the array and I was wondering how to access individual characters in the elements so that i can encrypt the individual characters. I'll be encrypting by modifying the ASCII code for the character. C++ by the way. . . Thanks!!!

#include<iostream>
#include<string>

using namespace std;

int main()
{
	string text;
	getline(cin, text);

	string separators = " ,.\"";

	size_t start = text.find_first_not_of(separators);
	size_t end = 0;

	int word_count = 0;

	while(start != string::npos)
	{
		end = text.find_first_of(separators, start + 1);
		if(end == string::npos)
		{
			end = text.length();
		}
		word_count++;

		start = text.find_first_not_of(separators, end + 1);
	}

	cout<<"Your text contained " << word_count << " words." <<endl;

	

	string** pstring_array = new string*[word_count];

	int index = 0;
	start = text.find_first_not_of(separators);
	
	while(start != string::npos && index <= word_count)
	{
		
		
		end = text.find_first_of(separators, start + 1);
		if(end == string::npos)
		{
			end = text.length();
		}
	
		pstring_array[index] = new string(text.substr(start, end - start));	
	
//		cout<< *pstring_array[index];
		index++;
		start = text.find_first_not_of(separators, end + 1);
		
	}
	
	cout<<"\n" << *pstring_array[0];	\\just a test

	return 0;

}

Share this post


Link to post
Share on other sites
Advertisement
0) If you're smart enough to use std::string, you should be smart enough to use std::vector. Note that your program leaks memory as is. Also, there is no real reason to dynamically allocate individual strings for the container, once you have a container (vector, dynamically allocted array, list, or anything else). The normal reasons for storing pointers in containers are

- You want to alias existing objects stored somewhere else, or "share" objects between containers

- You need to store objects of various derived classes of a common base in the container, and treat them polymorphically.

Note that by using a standard library container, you can also avoid pre-counting the objects (because the container can resize itself) or doing any counting at all (because the container keeps track of its count for you). This greatly simplifies the code (in addition to the simplification you get from not doing the memory management yourself).

1) You can access characters of a string by subscripting the string, just as if it were an array (or vector). Note that there is no one-past-the-end \0 character to subscript: the length of std::string("Hello") is 5 rather than 6, and std::string("Hello")[5] is undefined. (However, as usual, one-past-the-end iterators are actually quite useful; you just can't dereference them.)


// You don't need a space after '#include', but it sure is more readable :)
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main()
{
string text;
getline(cin, text);

string separators = " ,.\"";

size_t start = text.find_first_not_of(separators);
size_t end = 0;

vector<string> words;

while(start != string::npos)
{
end = text.find_first_of(separators, start + 1);
// This is a little strange, btw. Just using "break;" is OK.
// Better yet, rethink your loop condition :)
if(end == string::npos)
{
end = text.length();
}

// Look ma, no "new"!
words.push_back(string(text.substr(start, end - start)));

start = text.find_first_not_of(separators, end + 1);
}

cout << "Your text contained " << words.size() << " words." << endl;
cout << "\n" << words[0]; // test: shows a word
cout << "\n" << words[0][0]; // test: shows a character
}

Share this post


Link to post
Share on other sites
Hmmmm, that kindof makes sense. So how would I use cout << "\n" << words[0][0];
in a loop since \0 is not at the end of the string. How would it know where the end of the word is and then to move on to words[1][0]? Would I use npos?
Thanks again.

Share this post


Link to post
Share on other sites
Standard library containers know their size, and will report it via .size(); you can then proceed as if you had an array declared to be of that size (i.e. index from 0 to n-1 inclusive, by looping starting at 0, while < n). For std::string, .length() is provided as a synonym for .size().

However, for looping, you will often want to consider other methods, for example using iterators (all standard library containers provide .begin() and .end(); .begin() is an iterator to the zeroth element, and .end() is one-past-the-end; the usual idiom with iterators though is to loop while != end, rather than < end), or standard library algorithms (for_each, copy, remove_if, etc.)

Don't use npos; it's a constant value (typically -1, or else std::numeric_limits<unsigned int>::max()). Also it doesn't exist for vectors :)

This is actually a wart on the standard library design. Much of it was taken from the original STL (which in turn was actually originally written for Ada rather than C++), and because std::string was originally not designed as a "container" (and later got retrofitted as such), there is a fair amount of cruft hanging around. But it's still pretty good and saves a heck of a lot of time - and it's STANDARD - so please don't get any ideas ;)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement