Strange C++ std::string behavior... How can I fix this? - c++

This is driving me nuts. I have been at it for over 2 hours trying to figure this out...
Here is my problem. I am working on a fairly large program that works with Bayesian networks. Here is the main function:
using namespace std;
int main()
{
DSL_network net;
initializeNetwork(net);
setEvidence(net);
net.SetDefaultBNAlgorithm(7);
net.SetNumberOfSamples(80000);
cout << "Samples:\t" << net.GetNumberOfSamples() << endl;
updateEvidence(net);
//net.WriteFile("test.dsl");
return(DSL_OKAY);
}
This all works fine. The problem comes when I want to print out a string:
using namespace std;
int main()
{
//simple string creation
string a = "test";
//should print out "test"
cout << a << endl;
DSL_network net;
initializeNetwork(net);
setEvidence(net);
net.SetDefaultBNAlgorithm(7);
net.SetNumberOfSamples(80000);
cout << "Samples:\t" << net.GetNumberOfSamples() << endl;
updateEvidence(net);
//net.WriteFile("test.dsl");
return(DSL_OKAY);
}
Here is the output (just from printing the string a...):
   ▀ÇΦy♠≈6 ♦
What could be going on?
UPDATE:
int main()
{
//simple string creation
string a = "test";
//should print out "test"
cout << a << endl;
return(DSL_OKAY);
}
still prints
▀ÇΦy♠≈6 ♦
BIG UPDATE:
Here is the recent. I created a brand new project and pasted the code that Neil Butterworth posted (thanks btw). I ran the code and it printed correctly. Then I added the two .lib files to the Linker in the new project (smile.lib for the SMILE library, and wsock32.lib for socket use.)
I tried the code again, and it printed the first "test" correctly, then it printed the giberish. It is a problem with one of the .libs I am linking together. I tried each on their own to see if they are just clashing, and it seems that the smile.lib library is causing the problem. I will need to go into their documentation and figure out why.
Any ideas?
Thanks all for the help
Thanks

That's bizarre. I always like to break a problem down to it's minimal case. What does the following program do when you run it?
using namespace std;
int main() {
string a = "test";
cout << a << endl;
return 0;
}
If that works, then there's something else wrong and you need to add in one line at a time until it fails. Then examine that line very carefully ("I'm hunting wabbits").
Based on your edit, it may be a different string class being used. Try this:
int main() {
std::string a = "test";
std::cout << a << std::endl;
return 0;
}
Update:
Since it works in a new project and not the current one, check the following.
Make sure you're linking with the standard C++ runtimes.
make sure you don't #define string as something else (and the includes a -Dstring=somethingelse command line option to the compiler).
check the behavior using std::string, not just string.

Also try this:
int main()
{
//simple string creation
string a = "test";
const char* cStr = a.c_str();
//should print out "test"
cout << cStr << endl;
return(DSL_OKAY);
}
If the const char* line does not cause a compiler error, then we know that std::str is an 8 bit string. If the cout doesn't cause a compiler error, then we know that cout is defined for 8 bit chars. (And if the program produces the same result, then we're still confused :-}
EDIT (based on your comment below): I notice that the buggy output from "test" works out to 9 characters -- "▀ÇΦy♠≈6 ♦". Try other "test" strings such as, oh, "retest" or "foo". I suspect that your output will generally be 2x or 2x+1 the number of chars in the original string (12 or 13 for "retest", 6 or 7 for "foo".) This suggests that you're feeding 16-bit strings into an 8-bit buffer. I don't know how you can be getting that past the compiler, though -- perhaps you've got a faulty or out-of-date definition for std::string and/or cout?
EDIT 2: I remember where I've seen this before. A couple of years ago, I saw an issue where the DOS console window was corrupting the program's output. (I don't remember the exact details, but I think the problem was that the DOS console couldn't handle UTF-8 character sets.) If you're seeing this output in a DOS window (or, less likely, if it's being piped via system() to another program), then try re-directing it to a file, then open that file with Notepad. It just might work...

Check if
Do you have #include<iostream> and other relevant header includes?
net.GetNumberOfSamples() has a valid value AND
you are not mixing string and wstring.

Are you 100% that the source code file is ASCII? Try opening it in some hex editor.
Try typing (not copy/paste) the code in a completely new file and see what happens.
If that fails, then obviously something tinkers with your cout. Could you show us which libraries get linked into the executable? Maybe something closes stdout stream or something like that.

I would recommend slowly removing any #includes until you can find the one(s) that causes the issue.

You could try explicitly specifying the std namespace for the string type.
My main reason for suggesting you try this is that there could be a define in some of the included header files that replaces string with some other class or definition. Adding the namespace should force the macro to not be used.
One other thing to check would be to get a processed listing (or the assembly & source listing if you're feel like doing some assembly hacking) of the source code written out to a file and examine that to see what is happening.You'll probably find your answer there if nothing else.

Compile and run the following exact code; do not add any using directives.
#include <iostream>
#include <string>
int main() {
std::string s = "test";
for ( unsigned int i = 0; i < s.size(); i++ ) {
std::cout << s[i];
}
std::cout << "\n";
std::operator<<( std::cout, s );
std::cout << "\n";
}
If the loop prints "test" it means the string is OK and the problem is in the output. If the second "test" gets mangled, the problem is definitely in the output processing.

Does converting the std::string to a char string work.
ie:
cout << a << endl;
becomes
cout << a.c_str() << endl;

It seems very likely that you are mixing wchar and char, so that in your main the fixed chars are considered wide (2 bytes / char) or some unicode, and your lib for cout thinks they are simple 1 byte/char. I would look in the libraries that are linked with the project.
Unfortunately, I'm not exactly sure how to go about fixing this. There is almost certainly a setting somewhere for your project you can change (I don't have VS 2005 in front of me, unfortunately), but you're looking for things like wchar, t_char, or unicode.
I would be curious what happens if you use
string a("test");
instead of direct assignment.

is it possible that somewhere in another file within the same project, operator << is overloaded?
please try search for "operator <<" or "operator<<".

Suggestions:
call cout.flush prior to your cout << to see if you get the weird chars
try printf

Related

Which is the best way to print to the console in c++?

I have read three ways to print things to the console in c++ from various sources.
Using using namespace std; and then using cout (CodeBlocks Standard)
Not using the above and using std::cout and std::endl; (C++ Primer)
Using printf (HackerRank)
Which is preferred and why?
Number 2 with amendment. (std::cout and '\n')
Why?
Because you should avoid using namespace std. Source
(Among other reasons) Because cout is typesafe and printf is not. Source
std::endl will force a flush of the output buffer to the console. Unless you specifically want this to happen use << '\n' or << "...string\n". Source
Unless you really care about speed, both cout and printf are fine. If you want faster runtimes, here are a few pointers :
Use only printf with no cout. This will give more speed than using a mixture of printf and cout or just cout.
Or use only cout but add the following at the beginning of execution
ios_base::sync_with_stdio(false);cin.tie(NULL); . There are two separate streams for printf and cout and they are synchronized by default. Lot of running time is wasted due to this synchronisation. These two lines of code will stop the synchronisation, but take care that you don't use any printf if you add these lines, otherwise printing might happen in random order.
Do not use endl unless you want to flush the output buffer. Lots of endl can make the code slower. Use cout<<'\n'; instead.
these is my debugger code that during these 10 years of c++ working helped me.
std::ostream &debugRecord (const char* fileName, int lineNum, const char* funcName)
{
std::lock_guard<std::mutex> lock(streamMutex_);
return std::cout << "Thread # " << getCurrentThreadId() << " -- "
<< "(" << fileName << ":" << lineNum << "): " << funcName << std::endl;
}
Both your first points do basically the same thing. It's better practice to use std:: instead of using namespace std; as the latter pollutes the global namespace and can cause naming conflicts.
Something not mentioned is that you can selectively expose parts of a namespace with using <namespace>::<element>; (e.g. using std::cout;). It's still better practice to be verbose with your statements, but this option still isn't as bad as exposing the entire namespace.
printf isn't as safe as cout (the stream << operators do a good job of printing what you want), you ought to avoid it while starting out.
The answer depends a lot on what you want to do. For output which largely uses default formats cout is indeed preferred because of the type safety and because it's very intuitive.
If you want to heavily format your output though I can only recommend the surprisingly versatile and straight-forward printf because manipulators in cout are a pain. True: The printf format syntax, does, let's say, take some getting used to, but it's surely worth it. Just double check the format string, listen to the warnings of your compiler, and use the proper format specifiers e.g. for size_t and other system dependent data in order to stay portable.
There is also a boost facility for combining streams and printf style formatting, see https://stackoverflow.com/a/15106194/3150802, but I have never used it. Perhaps somebody can comment on its usability?

Weird value obtained when outputting

I have this simple program that basically accepts user input and outputs it to the screen. This program works fine when I input an integer. However, when I input a string literal, this negative integer is obtained as the output. (-858993460), regardless of any string input size.
I am currently using Visual Studio 2015 Community Edition, if that matters.
Here is my code.
#include "stdafx.h"
#include <iostream>
#include <string>
int main() {
int a;
std::string b;
b = "Type something";
std::cout << b << std::endl;
std::cin >> a;
std::cout << "You said " << a << std::endl;
}
I have tried searching but to no avail. Hence, I have two questions.
1) Why is it outputting this particular negative integer when I gave it a string input?
2) Why didn't the program give me a compilation error, syntax error, or a crash? Instead, why did it go on outputting that integer?
Sorry for my bad English.
1) Why is it outputting this particular negative integer when I gave it a string input?
Because your integer was not initialized to anything, it's outputting whatever is there (primitives like int do not get default values when declared at function-level scope). Reading of the integer from the stream failed because you provided a string literal, so the integer value was not changed. If you initialize the value of the integer to 42 you'll see that it's value was unchanged when it gets printed (until C++11. After C++11 the value will become 0).
2) Why didn't the program give me a compilation error, syntax error, or a crash? Instead, why did it go on outputting that integer?
streams force the programmer to check what happened (in general*). They have implicit conversions to booleans so you can conveniently check if anything went wrong.
Try to augment your code like so:
std::cin >> a;
if (!std::cin)
{
std::cerr << "Failed to read!" << std::endl;
exit(1);
}
Demo1
*If you want std::cin to throw an exception on failure, then you can use basic_ios::exceptions to do so:
std::cin.exceptions(std::istream::badbit | std::istream::failbit);
Demo2
There is already an excellent answer. I just want to add for the second question
2) Why didn't the program give me a compilation error, syntax error,
or a crash? Instead, why did it go on outputting that integer?
error?
The compiler cannot know what the user will write. It could it could be something that can be streamed to an int but it also could be that it cannot. Thus the compiler has no chance to issue a warning/error in this situation.
crash?
If this code would cause a crash then it would be impossible to use cin to write code that cannot be crashed by malformed user input. That would make cin rather useless.
conclusion?
It is your responsibility to check if the input operation went ok and to react accordingly if it didnt.
You're storing user input in an int.
I suggest you convert the input string to int as in
std::cin >> atoi(a);

Parsing arguments in C++

Firstly, I know my title looks like a commonly asked question, but hear me out. When I say 'Parsing arguments' I don't mean the command line arguments that get passed to the program when it starts up. I'm trying to create a seperate system to receive commands and parse them in runtime.
Main:
int main(int argc, char *args[])
{
cout << "Started up." << endl;
reloop();
}
// Main execution point. Prints text to the console and moves to a void:
void reloop()
{
char *str;
cin >> str;
parseargs(str);
}
// Starts waiting for inputted data, if found, move onto parseargs void.
void parseargs(char *args)
{
char *strings[10];
char delim[] = " ";
int i = 0;
strings[i] = strtok(args,delim);
if(strings[0] == "try")
{
cout << "WORKED!" << endl;
reloop();
}
else
{
cout << "Na. Didn't work." << endl;
reloop();
}
}
// Takes the arguments passed to it, splits them via a space and passes them to an array. From here, compares the first entry in the array to a command. If they equal, output success note.
Now, I'm a C# programmer for quite some time and have only just started C++.. What am I doing wrong? When the program starts up, an error comes up with:
Debug Assertion Failed!
Program: C:\Windows\system32\MSVCP110D.dll
File: c:\program files\microsoft visual studio 11.0\vc\include\istream
Line: 990
Expression: Invalid null pointer
*Note: I do have declarations for each function at the top of the CPP file.
One bug I can find in your code is in function void reloop()
char *str;
cin >> str; <---"Undefined behavior"
You don't allocate memory for str.
correct it either:
char str[SIZE];
Dynamically allocate space: char* str = new char[SIZE];
Next error is:
if(strings[0] == "try")
should be:
if(strcmp( strings[0], "try")!=0)
void reloop() {
char *str; /* WRONG */
cin >> str;
parseargs(str);
}
You should have written it that way :
void reloop() {
char str[BUF_MAX]; /* ok but take care of buffer overflow; maybe use std::string */
cin >> str;
parseargs(str);
}
Even if you know C# please note that you don't know anything about C++ and that even if you're very smart intuition will guide you down the wrong path (actually especially if you're very smart: C++ in quite a few parts is indeed "illogical" so a logic mind is not going to help at all).
The reason is that C++ is the way it is for a mix of complex reasons, including committee effect and a lot of historical heritage. No matter how smart you are you're not going to guess neither history nor what a committee decided.
How char * are part of C++ is one of these things that can only be understood if you know history (especially history of C). The error in you program is that you cannot write
char *str;
cin >> str;
because you didn't allocate the memory for it. It would also be bad code because potentially overflows the memory you allocate. If you're missing this then you're going to miss a LOT of other much more subtle points of C++ programming.
Do yourself a favor and start by reading cover-to-cover a good C++ book instead of just experimenting with a compiler.
Experimenting is not a reasonable path with C++ because of its very complex and sometimes illogical structure and because of "undefined behaviour" that means that when doing a mistake you cannot count on a clear error message but can get crazy behaviour instead (including the most dangerous crazy behaviour... i.e. the code apparently will work anyway even when a mistake is present).
Your code problem has been explained by others.
There is one more general problem with your code: you are not using existing functions or libraries which would do what you need.
Pure C solution:
http://www.gnu.org/software/libc/manual/html_node/Getopt.html
C++ Boost program options:
http://www.boost.org/doc/libs/1_54_0/doc/html/program_options.html

cin/cout with char[]

I am trying to build my overall expertise in C++ coming from VBA, so please forgive any glaring issues with my code... Using this simple program below, I am getting unexpected output.
#include <iostream>
int main() {
char f[]="", c[]="";
std::cin >> f;
std::cout << f << std::endl;
std::cin >> c;
std::cout << f << std::endl;
return 0;
}
When run, this is my result:
ABC (input)
f - ABC (output)
DEF (input)
f - EF (output)
Also tried as:
ABC DEF (input)
f - ABC (output)
f - EF (output)
I would expect that the output would be the same for both lines, since I THINK I'm only reading into f once. Moreover, if I am taking the cin and applying it to f, why does the first attempt read the entire string (ABC) while the second attempt is missing the D?
I tried also printing the result using this code, but the same problem occurs, so I'm assuming here that it's a problem with the cin and not cout.
for (j=0;j<3;j++) {
std::cout << f[j];
}
std::cout << std::endl;
Doing some research, I found this question, which looked promising, but when I changed my declaration from char f[] to char *f, I ended up with SEGFAULTs on the cin, while const char *f wouldn't even compile.
I am fumbling blindly here and would appreciate some guidance on how to correctly use cin and/or char arrays.
To reiterate my question: Why does the output std::cout << f << std::endl;, while not explicitly reassigning a value, vary in this way?
char f[]="", c[]="";
is equivalent to
char f[1]="", c[1]="";
i.e. it declares both f and c as arrays of one character (namely NUL or \0, the null terminator).
In other words, you're reading into both arrays past their end, which could work perfectly, could do very strange things (like you're seeing), could crash, or could make purple elephants erupt from your monitor next Tuesday.
It looks like you should use the getline function. There are two versions of it...
One is in the C++ standard library and is used this way:
std::string s;
// the following returns the stream that you give
// (the cast is non-functional, it's there to show the type)
(istream&)getline(cin, s);
The string object is nice for this because it dynamically sizes itself to hold whatever you receive.
The other getline is in the standard C library, at least on Mac OS X (run man 3 getline for more) and it uses FILE* instead of streams. That version is capable of dynamically reallocating a char array if you want it to, but you don't have to use it that way.
#include < iostream >
int main() {
char f[]="";
char c[]="";
Try these, it solve the problem for me ;D

Why does c_str() print the string twice?

So...
when I go:
cout<<stringName<<endl;
I get:
NT
But when I go:
cout<<stringName.c_str()<<endl;
I get:
NTNT
Why?
A quick test with the following code:
#include <string>
#include <iostream>
using namespace std;
int main(void) {
string str = "NT";
cout << str.c_str() << endl;
return 0;
}
produces one instance of NT so it looks like you probably have another output call somewhere.
A traditional C string (accessed through a char const*) has a sequence of characters terminated by a character 0. (Not the numeral 0, but an actual zero value, which we write as '\0'.) There's no explicit length — so various string operations just read one character at a time until it hits the '\0'.
A C++ std::string has an explicit length in its structure.
Is it possible that the memory layout of your string's characters looks like this:
'NTNT\0'
but the string's length is set to 2?
That would result in exactly this behavior — manipulating the std::string directly will act like it's just two characters long, but if you do traditional C operations using s.c_str(), it will look like "NTNT".
I'm not sure what shenanigans would get you into this state, but it would certainly match the symptoms.
One way you could get into this state would be to actually write to the string's characters, something like: strcat((char *)s.c_str(), "NT")
Show more code. It seems like you did cout << ealier and forgot that you did it. What does it print if you do cout<< "mofo" << stringName.c_str()<< "|||" << endl; Does it say NTmofoNT||| ? if so that may well be what happened ;)
This is not a problem with c_str(), but probably related to some other anomaly in the rest of the program.
Make a "hello world" application that does these same operations and you'll see it works fine there.