program doesn't print a values

Oct 29, 2017 at 1:12am
lm trying to print clark.race but it doesnt show anything. lm using a struct Dog. 'clark' and 'molly' are 'Dog' types.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct Dog {
   string name;
   string race;
};

int main () {

   Dog clark, molly;

   clark.name = "clark";
   clark.race = "red shepperd";

   printf ("%s %s", clark.name, clark.race); // it outputs only clark.name
   // clark.race appears to be empty.
   
   getch();
   return 0;
}


lm struggling with this.
Oct 29, 2017 at 1:42am
clark.name is a C++ string. You can print it like this:
 
    cout << clark.name;


printf() with the "%s" format string expects a C-string, which is a null-terminated character array, not a std::string.

You can convert to the required format using the c_str() member function, clark.name.c_str()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <string>
#include <cstdio>
#include <conio.h>

using namespace std;

struct Dog {
   string name;
   string race;
};

int main () {

   Dog clark, molly;

   clark.name = "clark";
   clark.race = "red shepperd";
   
   cout << "C++ string: " << clark.name << '\n';
   cout << "C-string:   " << clark.name.c_str() << '\n';

   printf ("%s %s\n", clark.name.c_str(), clark.race.c_str()); 
   
   getch();
   return 0;
}

Oct 29, 2017 at 1:49am
@vincentthorpe..

I see you're using C here, since you used printf, but I compiled it as a C++ program, and it works fine.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <conio.h>
#include <string>
#include <vector>

using namespace std;

struct Dog {
   string name;
   string race;
};

int main () {

   Dog clark, molly;

   clark.name = "Clark";
   clark.race = "red shepperd";

  cout << "My dog named " << clark.name << " is a " << clark.race;
   
   _getch();
   return 0;
}
Oct 29, 2017 at 2:29pm
thaks all. so if l want to use printf to print c++ style strings, l must be use cout. or c_str() method.

but is there no format form strings (%s) to output strings in c++ style ? using printf and without using c_str() method ?

like %string::str ?
thanks anyway my question is solved.

but know l have another question.

char *str = "my value",
is this a string? or a pointer?
and where pointing at ?
"my value" has an memory address?
Oct 29, 2017 at 6:47pm
std::printf() is defined in terms of the C standard library, which doesn't know anything about C++ strings. So there's no format specifier for C++ strings.

It's usually best to use cout anyways, because that interface avoids a number of significant problems with printf. Unfortunately, this added safety is bought at the expense of brevity. If you need to do complicated string formatting that would be too difficult or unreadable with cout, you could look into another library, like Boost.format.
http://www.boost.org/doc/libs/1_65_1/libs/format/

"my value" has a memory address?
Surprisingly, yes! Good observation.

Among all literals, only string literals (stuff in double quotes) have addresses. The (narrow string) literal itself is an array of type char const[]. In the jargon, we'd say that string literals are a kind of lvalue.

(Note: this exposes an error - the statement char *str = "my value" will not compile; it throws away the const. Many compilers do this as an extension for compatibility with C, but it is illegal regardless.)

Assuming we modify your example to compile:
char const *str = "my value";
Then the array "my value" undergoes the array-to-pointer conversion, yielding a pointer to the first element of the string literal (the 'm'), and that pointer is used to initialize str. String literals have static storage duration.
Last edited on Oct 29, 2017 at 6:48pm
Oct 31, 2017 at 9:24pm
@mbozzi
thank you alot for response

l remember my oldie professor (this man was incredible) in c++ used to use
char *str = "val";

to declare strings
we used borland builder a very old version in 2006

to get it clear...
1
2
3
4
5
   char const *s1 = "value"; // 'v','a','l','u','e','\0'
   char s2[6] = "value"; // 'v','a','l','u','e','\0'

   cout << s1 << endl;
   cout << s2 << endl;

these both are practicly the same c-string-style ?
and "value" is passing by reference too
Last edited on Oct 31, 2017 at 9:44pm
Nov 1, 2017 at 1:40am
these both are practically the same c-string-style ?
and "value" is passing by reference too

The only things that get "passed" are function arguments. For historical reasons, arrays (and functions) cannot be passed as function arguments by value. But initialization follows different rules.

Here
 
  char const *s1 = "value"; // 'v','a','l','u','e','\0' 
Attempts the initialization of a char const* from an array of const char. This requires the array-to-pointer conversion I mentioned. But here
 
   char s2[6] = "value"; // 'v','a','l','u','e','\0' 
Attempts the initialization of a char array from a const char array. It is equivalent to
char s2[6] = {'v', 'a', 'l', 'u', 'e', '\0'}; - that is, s2 holds a copy of the contents of the string literal, while s1 points to the string literal.

You can freely change *s2, but attempting to change *s1 (after applying const_cast to get a pointer to non-const) would cause your program's behavior to be undefined.

( Note: If you want the details, initialization of arrays is an example of aggregate initialization. See: http://en.cppreference.com/w/cpp/language/aggregate_initialization )
Last edited on Nov 1, 2017 at 3:02am
Nov 8, 2017 at 1:34pm
thanks @mbozzi . lm in the good way now
Topic archived. No new replies allowed.