简体   繁体   中英

Strange C++ std::string behavior… How can I fix this?

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.

我建议您慢慢删除所有#include,直到找到导致该问题的一个。

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM