Why does these two code pieces give different results [duplicate] - c++

This question already has answers here:
C++ Comparison of String Literals
(8 answers)
Closed 2 years ago.
I was trying to learn about "<" operator on c++ strings and tried some test cases. I realized the two codes which I thought should behave the same was giving different results. Below are the codes, what is the reason for this?
string s="test";
string k="tes";
cout<<(s<k)<<endl; //returns false so it prints 0
cout<<("test"<"tes")<<endl; // returns true so it prints 1

(s < k) compares the values of the strings as you would expect.
("test" < "tes") compares the pointers to the beginning of the string literals as the compiler decides to arrange them in memory. Therefore, this comparison may return 0 or 1 depending on the compiler and settings in use, and both results are correct. The comparison is effectively meaningless.
The "C way" to compare these string literals would be strcmp("test", "tes").

s and k are string objects for which a comparison operator has been defined and performs what you expect.
"test" and "tes" are pointers to char that hold the address of the locations where these characters are stored. Thus the comparison is on the addresses.

Related

Why does string concatenation fail when resize is used in cpp? [duplicate]

This question already has answers here:
What is an off-by-one error and how do I fix it?
(6 answers)
Closed 1 year ago.
I came across a scenario where string concatenation is failing in C++. But I don't see a reason for it to fail.
Code sample is as below:
int main()
{
std::string a;
std::string b = "bbbbbbb";
a.resize(10);
for (int i = 0; i <= 5; i++) {
a[i] = 'a';
}
a = a+b;
printf("\n%s\n", a.c_str());
}
It is outputting aaaaaa.
I was expecting it to output aaaaaabbbbb. If I change a.resize(10); to a.resize(5); I am getting the expected output.
Would be helpful if someone could help me in understanding the behaviour?
In addition to the off-by-one error, after concatenation, the contents of a in main are:
aaaaa\0\0\0\0\0bbbbb
So: five 'a' bytes, then five zero bytes, then five 'b' bytes. The string is fifteen bytes long.
printf, like other C functions, doesn't know about this size, and instead takes the length of the string to be until the first zero byte. In your case, that is "aaaaa".
To print the entire string, use something like std::cout. If you're certain you want printf, it is also possible to pass a length to that with the %.*s specifier.
std::string a;
a.resize(10);
gives you a string of size 10 but whose content is undefined.
You set the first 5 character to something specific and append some more characters to the end. But characters 5-10 never get set to something.
In the execution you are seeing, these characters happen to be zero, but printf – as a C style function — considers the appearance of a null character the end of the string. Therefore it stops printing.

String comparison of char* to uint8_t [duplicate]

This question already has an answer here:
Comparing uint8_t data with string
(1 answer)
Closed 4 years ago.
I'm new to C and C++, and can't seem to work out how I need to compare these values:
Variable I'm being passed:
typedef struct {
uint8_t ssid[33];
String I want to match. I've tried both of these:
uint8_t AP_Match = "MatchString";
unsigned char* AP_Match = "MatchString";
How I've attempted to match:
if (strncmp(list[i].ssid, "MatchString")) {
if (list[i].ssid == AP_Match) {
if (list[i].ssid == "MatchString") {
// This one fails because String is undeclared, despite having
// an include line for string.h
if (String(reinterpret_cast<const char*>(conf.sta.ssid)) == 'MatchString') {
I've noodled around with this a few different ways, and done some searching. I know one or both of these may be the wrong type, but I'm not sure to get from where I am to working.
There is no such type as "String" defined by any C standard. A string is just an array of characters that are stored as unsigned values based on the chosen encoding. 'string.h' provides various functions for comparison, concatenation, etc. but it can only work if the values you are passing to it are coherent.
The operator "==" is also undefined for string comparisons, because it would require comparing each character at each index, for two arrays that may not be the same size and ultimately may use different encodings, despite the same underlying unsigned integer representation (raising the prospect of false positive comparisons). You can possibly define your own function to do it (note C doesn't allow overloading operators), but otherwise you're stuck with what the standard libraries provide.
Note that strncmp() takes a size parameter for the number of characters to compare (your code is missing this). https://www.tutorialspoint.com/c_standard_library/c_function_strncmp.htm
Otherwise you would be looking at the function strcmp(), which requires the input strings to be null-terminated (last character equal to '\0'). Ultimately it's up to you to consider what the possible combinations of inputs could be and how they are stored and to use a comparison function that is robust to all possibilities.
As a final side note
if (list[i].ssid == "MatchString") {
Since ssid is an array, you should know that when you do this comparison, you are not actually accessing the contents of ssid, but rather the address of the first element of ssid. When you pass list[i].ssid into strcmp (or strncmp), you are passing a pointer to the first element of the array in memory. The function then iterates over the entire array until it reaches the null character (in the case of strcmp) or until it has compared the specified number of elements (in the case of strncmp).
To match two strings use strcmp:
if (0==strcmp(str1, str2))
str1 and str2 are addresses to memory holding a null terminated string. Return value zero means the strings are equal.
In your case one of:
if (0==strcmp(list[i].ssid, AP_Match))
if (0==strcmp(list[i].ssid, "MatchString"))

How to compare two strings in C++ [duplicate]

This question already has answers here:
Differences between C++ string == and compare()?
(9 answers)
Closed 7 years ago.
Lets say I have string a and string b
I know I have to use a.equals(b) to compare two strings but in C++, it looks like I can directly use if(a==b)..., and I also found that string has a compare() fuction, so which one should I use, == or compare()
use == when you want to test for equality. It call str1.operator ==(str2)
Use std::string::compare if you want to know whether string is less than, equal to or greater than other string. std::string::compare returns a negative number (if str1 is lexicographycally or in dictionary order less than str2), 0 or a positive number accordingly. (analogous to str1 - str2)

Merge sort on array of string C

Is it possible to merge sort an array of strings? For example if I have an array of strings in C like...
arr[0]="Hello";
arr[1]="cat";
arr[2]="there";
arr[3]="apple";
arr[4]="flower";
The sorted output should be...
apple
cat
flower
hello
there
Also I don't understand what I should do if I have 2 words like "Hello" and "Hell?" Everywhere the examples are always for integers and never strings especially in C++.
Yes, in your comparision, use strcmp for C, and std::string::compare for C++. Both functions will compare the strings, and return an integer with the following meanings...
< 0 — Either the value of the first character that does not match is lower in the compared string, or all compared characters match but the compared string is shorter.
= 0 — They compare equal
> 0 — Either the value of the first character that does not match is greater in the compared string, or all compared characters match but the compared string is longer.
This will also take into account "Hello" vs. "Hell" and will will subsequently sort "Hell" before "Hello".
Note: If you find that you are like me, and have a hard time remembering what the result means. Simply put the comparison operator (as in the example above) inbetween str1 and str2. So, for example, if you called strcmp(str1, str2) and the result was < 0, then look at it like str1 < str2.

Arguments parsing error [duplicate]

This question already has answers here:
Using the equality operator == to compare two strings for equality in C [duplicate]
(9 answers)
Closed 8 years ago.
I am trying to parse the run-arguments within my console application with this code:
int _tmain(int argc, _TCHAR* argv[])
{
if(argv[1] == _T("arg1")) cout<<"Argument1 was passed";
_getch();
return 0;
}
My code doesn't work. I mean, it runs, but the console is empty.
I am compiling with Use Unicode Character Set option in Visual Studio 2012 (on Windows 7).
Where is my mistake?!
Use strcmp to compare char arrays
if(strcmp(argv[1], "arg1") == 0)
Use of == just compares pointers to two different strings.
See Darius Kucinskas' answer for comparing _TCHAR arrays
if (_tcscmp(argv[1], _T("arg1")) == 0) {
cout << "Argument1 was passed" << endl;
}
You have a few mistakes:
1) You cannot compare C-style strings (character arrays) using the == operator. argv[#] is a character array, as is _T("some value"). In order to compare them, you need to use strcmp (or one of it's cousins), or store it in a std::string.
2) You are attempting to access the 2nd element of the array, but only 1 element exists. you said you were passing nothing to the call, meaning argv[0] will contain data (the name of the executable you are running), but argv[1] will not. In general, attempting to access it will be attempting to access data outside the range of the array with undefined results. In this particular case, the standard (Section 3.6.2) states that it will always be 0 (aka NULL). So your conditional will always be false.
3) You should ALWAYS check the value of argc when command line parameters are expected.