cin/cout with char[] - c++

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

Related

C++ Adding to a string (Output)

Below is a cout of a c++ statement:
cout << "TESTING" + 2 << endl;
I understand why this statement will print out sting. But the question I have is if I do the code below it will cause an error. I don't understand why as this is the same thing. Sorry for a basic question I am new to c++.
string t = "TESTING";
cout << t + 2 << endl;
Thanks in advance for any help. :)
This is an interesting case. I'm not sure if you've actually printed the result of your first statement or not, but if you do you see that you are actually getting "STING" and not "TESTING2", or something like that!
There are a few things going on here. In your first statement, you are constructing a string using a string literal. In this case, C++ create a const char[N] and put your string into it. Since char[N] is technically an array (and array is a pointer), the operator + acts as increment and the result of "TESTING" + 2 is actually a pointer to the second element of "TESTING", which is "STING". You'll not see any errors, because C++ thinks that what's you wanted to do.
In your second statement, you are telling C++ that I want a std::string object. The std::string is by design safer and will nag at you if you try to add anything other than a string to it. So, when you do, you get an error. For your second statement to work as intended, you should write t + std::to_string(2).
It is important to know the difference between string and char types. String is a class that manages string of characters. And char[] is an array of characters. Refer this question for the explanation. In your case the code will work if you do:
#include <iostream>
int main ()
{
char t[] = "TESTING";
std::cout << t + 2 << std::endl;
return 0;
}
If you want to concatenate string with int then you should explicitly convert it:
#include <iostream>
int main ()
{
std::string m = "Testing ";
std::cout << m + std::to_string(2) << std::endl;
return 0;
}

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

In C++, I thought you could do "string times 2" = stringstring?

I'm trying to figure out how to print a string several times. I'm getting errors. I just tried the line:
cout<<"This is a string. "*2;
I expected the output: "This is a string. This is a string.", but I didn't get that. Is there anything wrong with this line? If not, here's the entire program:
#include <iostream>
using namespace std;
int main()
{
cout<<"This is a string. "*2;
cin.get();
return 0;
}
My compiler isn't open because I am doing virus scans, so I can't give the error message. But given the relative simplicity of this code for this website, I'm hoping someone will know if I am doing anything wrong by simply looking.
Thank you for your feedback.
If you switch to std::string, you can define this operation yourself:
std::string operator*(std::string const &s, size_t n)
{
std::string r; // empty string
r.reserve(n * s.size());
for (size_t i=0; i<n; i++)
r += s;
return r;
}
If you try
std::cout << (std::string("foo") * 3) << std::endl
you'll find it prints foofoofoo. (But "foo" * 3 is still not permitted.)
There is an operator+() defined for std::string, so that string + string gives stringstring, but there is no operator*().
You could do:
#include <iostream>
#include <string>
using namespace std;
int main()
{
std::string str = "This is a string. ";
cout << str+str;
cin.get();
return 0;
}
As the other answers pointed there's no multiplication operation defined for strings in C++ regardless of their 'flavor' (char arrays or std::string). So you're left with implementing it yourself.
One of the simplest solutions available is to use the std::fill_n algorithm:
#include <iostream> // for std::cout & std::endl
#include <sstream> // for std::stringstream
#include <algorithm> // for std::fill_n
#include <iterator> // for std::ostream_iterator
// if you just need to write it to std::cout
std::fill_n( std::ostream_iterator< const char* >( std::cout ), 2, "This is a string. " );
std::cout << std::endl;
// if you need the result as a std::string (directly)
// or a const char* (via std::string' c_str())
std::stringstream ss;
std::fill_n( std::ostream_iterator< const char* >( ss ), 2, "This is a string. " );
std::cout << ss.str();
std::cout << std::endl;
Indeed, your code is wrong.
C++ compilers treat a sequence of characters enclosed in " as a array of characters (which can be multibyte or singlebyte, depending on your compiler and configuration).
So, your code is the same as:
char str[19] = "This is a string. ";
cout<<str * 2;
Now, if you check the second line of the above snippet, you'll clearly spot something wrong. Is this code multiplying an array by two? should pop in your mind. What is the definition of multiplying an array by two? None good.
Furthermore, usually when dealing with arrays, C++ compilers treat the array variable as a pointer to the first address of the array. So:
char str[19] = "This is a string. ";
cout<<0xFF001234 * 2;
Which may or may not compile. If it does, you code will output a number which is the double of the address of your array in memory.
That's not to say you simply can't multiply a string. You can't multiply C++ strings, but you can, with OOP, create your own string that support multiplication. The reason you will need to do that yourself is that even std strings (std::string) doesn't have a definition for multiplication. After all, we could argue that a string multiplication could do different things than your expected behavior.
In fact, if need be, I'd write a member function that duplicated my string, which would have a more friendly name that would inform and reader of its purpose. Using non-standard ways to do a certain thing will ultimately lead to unreadable code.
Well, ideally, you would use a loop to do that in C++. Check for/while/do-while methods.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int count;
for (count = 0; count < 5; count++)
{
//repeating this 5 times
cout << "This is a string. ";
}
return 0;
}
Outputs:
This is a string. This is a string. This is a string. This is a string. This is a string.
Hey there, I'm not sure that that would compile. (I know that would not be valid in c# without a cast, and even then you still would not receive the desired output.)
Here would be a good example of what you are trying to accomplish. The OP is using a char instead of a string, but will essentially function the same with a string.
Give this a whirl:
Multiply char by integer (c++)
cout<<"This is a string. "*2;
you want to twice your output. Compiler is machine not a human. It understanding like expression and your expression is wrong and generate an error .
error: invalid operands of types
'const char [20]' and 'int' to binary
'operator*'

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.
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