views:

383

answers:

9

First off, this is a "homework" question so vector libraries and string libraries are off limits. I'm trying to get to the basics of c++.

My intention with this code is to make and use an array of string arrays. A list of words in other words.

When I run this code I get a bunch of nonsense.

If there is a better way to make a list of words in c++, I would love to hear about it.

const int cart_length = 50;
const int word_length = 50;

int main()
{

char cart_of_names[cart_length][word_length]; 
float cart_of_costs[cart_length];

char name[word_length];
cout << "enter the name of the first item: ";
cin >> name;
for(int i=0; i<word_length; i++)
{
 cart_of_names[0][i] = name[i];
}
cout << endl;
cout << "that is: ";
for(int x=0; x<word_length; x++)
{ 

  cout << cart_of_names[0][x];
}
cout << endl;

return 0;
}
A: 

If you can't use std::string, at least look at the functions like strncpy() from C for your name copying. Also, you're forgetting that c-style strings are null terminated.

Calyth
A: 

If you use strcpy() instead of cart_of_names[0][i] = name[i];

it may work better but I cringe just looking at all that code.

Tim
"First off, this is a "homework" question so vector libraries and string libraries are off limits."
Jodi
@Jodi - somehow I missed that. Never mind then. That's not C++ then, that is straight C.
Tim
+4  A: 

If the string entered is not 50 characters long (cart_length), then less than 50 characters will be valid in the name. You should have an if(cart_of_names[0][x]==0) break; in your second loop.

Adisak
Oh, and like other posters mention, if you can use the clib strXXX() functions, you should be using them. If your homework is to directly manipulate chars as part of the string, then you need to have the null check I mention to determine when a string terminates.
Adisak
It doesn't matter if less than 50 characters are valid. He's allocated name to 50 characters so he can copy "name\0garbageupto50chars" around all he likes. The cin>>name; and the cout<<cart_of_names[x]; will handle the null byte for him (as long as name is shorter than 50 chars of course). IOW, he's using memcpy instead of strncpy. No big deal.
jmucchiello
@jmucchiello -- Sorry but you're wrong... he's not outputting cout<<cart_of_names[x]; (the whole string @ offset X) but rather cout<<cart_of_names[0][x]; (each char X of string @ offset 0). In this case, he does need to be concerned about invalid characters and to check for NULL termination in cart_of_names[0] while outputting the characters of that string.
Adisak
This worked wonderfully. I had something similar that I couldn't get to work, but this did it. Thank you, and I'm once again amazed by this community.
peter
A: 

Unless you're forbidden to use STL (which would be just mean), just use std::list<std::string>. www.cplusplus.com has detailed descriptions and examples for those classes.

Otherwise, you're stuck with an array of char arrays: in that case, be prepared for a lot of buffer overflow errors. Look around on the above site for the char[] management functions (strncpy() and the like), they'll make your life a bit easier (but not a lot).

suszterpatt
+2  A: 

I don't exactly understand what you are looking for. Following code will help you to read and print a list of 50 words. Hope this would help you.

const int cart_length = 50;
const int word_length = 50;

int main()
{

    char cart_of_names[cart_length][word_length]; 
    float cart_of_costs[cart_length];

    for(int i=0; i<cart_length; i++)
    {
     cout << "enter the name of the " << i + 1 << "th item: ";

     cin >> cart_of_names[i];
    }

    cout << "that is: ";

    for(int x=0; x < cart_length; x++)
    {       
     cout << cart_of_names[x] << endl;
    }

    return 0;
}
Vadakkumpadath
This was much simpler, than I was making it. Thanks.
peter
A: 

In C, the best way I found to conceptualize what you are trying to do is using an array of char*. Same effect, but if you start to work with it I believe you may find it is easier on the brain.

Bill K
A: 

It looks pretty close to me. Strings in C are null-terminated, which means that the end of the string is indicated by a null character. In a sense, a string in C is really just an array of bytes.

When you do:

cout << "enter the name of the first item: ";
cin >> name;

If I enter the string "Book", in memory it'll look like something like:

|0|1|2|3|4|5..49|
|B|o|o|k|0|*HERE BE DRAGONS*

Well, really it will contain the ASCII values corresponding to those letters, but for our purposes, it contains those letters. There here be dragons is memory that that you didn't initialize, so it contains whatever garbage your platform sets it to.

So when you copy your string, you need to instead look for that 0 byte at the end of the string.

for(int i=0; name[i]!=0; i++)
{
    cart_of_names[0][i] = name[i];
}

Then when you output it, you don't actually need to do it a character at a time. You can just do cout<<cart_of_names[0]. cout knows where the string ends because of that terminating null character.

notJim
For reference, 0 == NULL right now, which is why he is checking `name[i] != 0`; `name[i]` returns a reference (the actual character).
Hooked
This would only work properly if cart_of_names[0][*] is an array of zeroes.
sharth
@sharth: I don't understand, why?
notJim
A: 

"If there is a better way to make a list of words in c++, I would love to hear about it."

Include #include <string> and use std::string. The std::string type is part of the C++ specification, I think.

#include <iostream>
#include <string>

int main(void) {
  std::string list[7];

  list[0] = "In C++";
  list[1] = "you can use";
  list[2] = "the `std::string` type.";
  list[3] = "It removes";
  list[4] = "many of the problems";
  list[5] = "introduced by";
  list[6] = "C-style strings.";

  for (int k=0; k<7; k++) std::cout << list[k] << ' ';
  std::cout << '\n';
  return 0;
}
pmg
+2  A: 

Check out STLSoft's fixed_array_2d (and it's higher order siblings). There's a detailed discussion of how they're implemented for maximum performance in Matthew Wilson's Imperfect C++.

dcw