Thread: Adding character arrays to strings.

  1. #16
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    and does anybody know how tonto's idea works / what it is?
    In C++, string types are much easier to work with than c-style strings which are char arrays. With string types, you can use + to add strings together and == to compare strings. With char arrays, you have to use the functions strcat() and strcmp() respectively to do those tasks. Additionally, strcat() requires that the destination array be big enough to hold both strings plus one additional character('\0') at the end.

    The problem is that when creating an ofstream object in order to write to a file, e.g.
    Code:
    std::ofstream out("dec_" + argv[1]);
    the ofstream constructor requires a char array, i.e. what's inside the parentheses must be a char array. Your statement is incorrect because you can't use + to add a string literal, like "dec", and a char array together. The compiler considers the string literal a char array, so as far as the compiler is concerned, you are adding two char arrays together using +, and you can only use + to add string types together.

    What Tonto's example does is it first turns the string literal into a string type:

    std::string("dec_")

    Since you can add char arrays to a string type, the code then adds argv[1] to the string type
    Code:
    (  std::string("dec_") += argv[1]  )
    In regards to what += does, this:
    Code:
    string str = "hello";
    str = str + " world";
    is equivalent to:
    Code:
    string str = "hello";
    str += " world";
    So Tonto's example ends up with this format:
    Code:
    std::ofstream out(string Type in here)
    But, we know that won't do because the ofstream constructor takes a char array as an argument--not a string type. Well, the string class has a function called c_str(), and it returns the string in the form of a char array. So, Tonto's example does this:
    Code:
    (std::string("dec_") += argv[1]).c_str()
    In summary, the example first turns the string literal "dec_" into a string type, then it adds the char array argv[1] to the string type, and finally it converts the resulting string type to a char array so that the ofstream constructor gets the proper argument type.
    Last edited by 7stud; 02-05-2006 at 02:47 PM.

  2. #17
    Registered User
    Join Date
    Dec 2005
    Posts
    52
    so what does the .c_str() function do?

    also, what are stringstreams?

    dwks - what if the filename is longer than the number of chars? doesn't happen much, but the other day i wrote a program to generate html slideshows using a bunch of URLs / file paths, and a lot of the ones i used to test it were pretty long.

  3. #18
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    .c_str() returns a const char *, which is a pointer to a character array so that an instance of the string class can be used in a situation where the function expects a C style array. In this case, you have a string, but the ofstream constructor takes a char array, so you use the c_str() function of the string class to pass a char array with the same contents as the string holds.

    A stringstream is like cin or cout, or like a file stream, in that it reads and/or writes data, including numbers and text. The difference is that instead of writing and reading from the console or a file, a stringstream writes and reads from a string. It's used to create a string from a bunch of data, or read data from an existing string.

    If the filename is longer than the number of chars, then you have to make your array bigger. This is one of the reasons character arrays are harder than C++ strings. A C++ string resizes itself to hold whatever input you give it. For a locally defined character array, there is no resizing.

  4. #19
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    so what does the .c_str() function do?
    Did you see this:
    the string class has a function called c_str(), and it returns the string in the form of a char array.

  5. #20
    Registered User
    Join Date
    Dec 2005
    Posts
    52
    sorry, i either didn't see your post (7stud) or you posted while i was typing... oops.

    thanks

  6. #21
    Registered User
    Join Date
    Dec 2005
    Posts
    52
    ok i've decided to add .enc to the filename (so blah.txt becomes blah.txt.enc) when encoding, and strip the last 4 characters (blah.txt.enc -> blah.txt) when decoding - action taken, encoding or decoding, is determined from filename.

    this is probably really inefficient -- but i couldn't think of how else to do it. not to mention, this doesn't work.

    Code:
      char* filename[leng(argv[1]) - 4];
      if (enc) {
        std::memcpy(filename, argv[1], length - 4);
        (filename + length - 3) = new char;
        (filename + length - 2) = new char;
        (filename + length - 1) = new char;
        (filename + length) = new char;
        filename[length - 3] = argv[1][length - 3];
        filename[length - 2] = argv[1][length - 2];
        filename[length - 1] = argv[1][length - 1];
        filename[length] = '.';
        (filename + length + 1) = new char;
        (filename + length + 2) = new char;
        (filename + length + 3) = new char;
        filename[length + 1] = 'e';
        filename[length + 2] = 'n';
        filename[length + 3] = 'c';
      }
      else {
        std::memcpy(filename, argv[1], length - 4);
      }
    enc is a boolean, if true then it's encoding the file and should append .enc to the file -- etc.
    length is a variable containing the length of argv[1][].

    i couldn't think of how to do this with vectors, but this doesn't work either. any ideas?

  7. #22
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Why make things so difficult for yourself?

    Code:
    	std::string filename = argv[1];
    	if(enc)
    	{
    		filename += ".enc";
    	}
    	else filename = filename.substr(0, filename.rfind("."));

  8. #23
    Registered User
    Join Date
    Dec 2005
    Posts
    52
    WHOA it works
    can you explain how it works? (all i don't get is the substr and rfind functions....)

  9. #24
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    http://www.cppreference.com/cppstring/index.html

    So rfind returns the index of the last '.' and substr creates a substring starting at index 0 (the first character) and containing the number of characters equal to the index returned by rfind. Follow it with an example like "sample.txt" to see how it become "sample".

  10. #25
    Registered User
    Join Date
    Dec 2005
    Posts
    52
    sweet.

    another question by me..... the ternary operator only accepts one line , right? or does it? i'm confused about it. what does it allow? for example, (is (true) ? blah; return blah; : std::cout << "BLAH?"; return blah * 2) valid?

  11. #26
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    C++ does not care about whitespace, and your expression can be as many lines as you want. Here's what MSDN says about the ternary (conditional operator): http://msdn.microsoft.com/library/de...l_Operator.asp

    The conditional operator (? is a ternary operator (it takes three operands). The conditional operator works as follows:

    * The first operand is implicitly converted to bool. It is evaluated and all side effects are completed before continuing.
    * If the first operand evaluates to true (1), the second operand is evaluated.
    * If the first operand evaluates to false (0), the third operand is evaluated.

    The result of the conditional operator is the result of whichever operand is evaluated — the second or the third. Only one of the last two operands is evaluated in a conditional expression.

    Conditional expressions have right-to-left associativity. The first operand must be of integral or pointer type. The following rules apply to the second and third expressions:

    * If both expressions are of the same type, the result is of that type.
    * If both expressions are of arithmetic or enumeration types, the usual arithmetic conversions (covered in Arithmetic Conversions) are performed to convert them to a common type.
    * If both expressions are of pointer types or if one is a pointer type and the other is a constant expression that evaluates to 0, pointer conversions are performed to convert them to a common type.
    * If both expressions are of reference types, reference conversions are performed to convert them to a common type.
    * If both expressions are of type void, the common type is type void.
    * If both expressions are of a given class type, the common type is that class type.
    Your code:

    Code:
    (true) ? blah; return blah; : std::cout << "BLAH?"; return blah * 2
    Is invalid, you may not return. You may substitute the semi-colons for commas to evaluate multiple expressions however.

  12. #27
    Registered User
    Join Date
    Dec 2005
    Posts
    52
    ahh. commons instead of semicolons. got it.

  13. #28
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Of course, it would be better to just use an if/else statement unless you are purposefully trying to obfuscate the code.

  14. #29
    Registered User
    Join Date
    Dec 2005
    Posts
    52
    idk i just fell in love with the ternary operator. for one / two line things. it's SO COOL!
    i don't even know why.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Manipulating Character arrays in functions.
    By kbro3 in forum C++ Programming
    Replies: 11
    Last Post: 08-16-2008, 02:24 AM
  2. Strings and Substrings using arrays
    By dcwang3 in forum C Programming
    Replies: 12
    Last Post: 02-18-2008, 07:28 AM
  3. copying strings to heap character arrays
    By SkyRaign in forum C++ Programming
    Replies: 4
    Last Post: 11-26-2006, 02:08 PM
  4. Replies: 2
    Last Post: 02-23-2004, 06:34 AM
  5. Storing strings in 2d char arrays problem
    By rainmanddw in forum C++ Programming
    Replies: 5
    Last Post: 10-22-2003, 05:41 PM