-2

When I printed it I got error like this 17:1733╠╠╠╠╠╠╠╠17:╠╠. I couldn't figure it out. I would appreciate if you solve and give me a better approach? Thanks for your help.

#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <cstdlib>
#include <iomanip>
#include <string>
using namespace std;

int main()
{


    char* time = "173324";

    char holdh[3];
    char holdM[3];
    char holds[3];
    holdh[2] = '\0';
    holdM[2] = '\0';
    holds[2] = '\0';

    int t;
    for (t = 0; t < 6;t++)
    {
        if (t < 2)
            holdh[t] = *(time + t);
        else if (2 <= t < 4) {
            t = t - 2;
            holdM[t] = *(time + t);
            t = t + 2;
        }
        else if (4 <= t < 6)
        {
            t = t - 4;
            holds[t] = *(time + t);
            t = t + 4;
        }
    }


    string h(holdh);
    string M(holdM);
    string s(holds);
    string datex = h + ":" + M + ":" + s;
    cout << datex;
    return 0;
}

It might be overflow of memory but I tried to prevent that by assigning null values. So if I have a problem in there too please inform. Thanks again.

CKE
  • 1,533
  • 19
  • 18
  • 29
  • Don't forget that literal strings are really arrays of ***constant*** characters, so your pointer `time` should be of type `const char*`. – Some programmer dude Sep 12 '18 at 07:33
  • what s _expected_ output? – Swift - Friday Pie Sep 12 '18 at 07:35
  • `╠` is 0xCC in codepage 437. So basically you're printing a bunch of 0xCC "╠╠╠╠╠╠╠" which means you [printed some uninitialized memory](https://stackoverflow.com/q/370195/995714), probably due to a non-terminating C string – phuclv Sep 12 '18 at 08:04
  • @phuclv `std::string` are not c-strings, they are not null-terminated – 463035818_is_not_an_ai Sep 12 '18 at 09:07
  • @user463035818 I've yet to look at the code but std::string does contain a null-terminated string which can be accessed with `data()` or `c_str()` – phuclv Sep 12 '18 at 09:17
  • [Is (4 > y > 1) a valid statement in C++? How do you evaluate it if so?](https://stackoverflow.com/q/8889522/995714), [Language support for chained comparison operators (x < y < z)](https://stackoverflow.com/q/4090845/995714), [Why does (0 < 5 < 3) return true?](https://stackoverflow.com/q/4089284/995714) – phuclv Sep 12 '18 at 09:20
  • @phuclv you get a null terminated c string when you call `c_str`, but that doesnt mean that `std::string` is a c string. If you dont believe me check this out `std::string s = "asdasd"; s[1] = '\0'; std::cout << s.size();` – 463035818_is_not_an_ai Sep 12 '18 at 09:20
  • @user463035818 I didn't say that std::string is a C-string and you can mutate the string like that. I'm talking about the place the OP constructs the std::string from `holds` and if he forgot to null-terminate that array, the output will be undefined – phuclv Sep 12 '18 at 09:33

2 Answers2

4

The expression 2 <= t < 4 is equal to (2 <= t) < 4. That is, check if the result of 2 <= t (which is a bool true or false) is smaller than 4, which is will always be as boolean results are either 0 (for false) or 1 (for true).

If you want to compare a range, you need to to e.g. 2 <= t && t < 4.


More generally, I advice you to not use a loop for this. Do the assignments directly instead:

// Create three arrays and initialize all elements to zero
char holdh[3] = {};
char holdM[3] = {};
char holds[3] = {};

holdh[0] = time[0];
holdh[1] = time[1];
holdM[0] = time[2];
holdM[1] = time[3];
holds[0] = time[4];
holds[1] = time[5];

Much simpler and show your intent much more clearly.


And you don't even need the temporary holdX variables, as you can just get the sub-strings from time and initialize h, M and s directly:

const char* time = "173324";

std::string h(time + 0, time + 2);
std::string M(time + 2, time + 4);
std::string s(time + 4, time + 6);

And do you really need the also temporary h, M and s variables?

std::cout << std::string(time + 0, time + 2) << ':'
          << std::string(time + 2, time + 4) << ':'
          << std::string(time + 4, time + 6) << '\n';

And do you really need freshly allocated strings?

std::cout << std::string_view(time + 0, 2) << ':'
          << std::string_view(time + 2, 2) << ':'
          << std::string_view(time + 4, 2) << '\n';
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

Your code is an textbook example of bad use of if() statement inside of loop.

What happens that you repeat all same checks in every iterations, while you actually know where iterations must stop.

And you made assumption that if() checks every comparison inside its expression. It doesn't. It evaluates expression and checks if result is equivalent of non-zero value or boolean true. Thus if(4 <= t < 6) is a bug. It's an equivalent of if( (4 <= t) < 6 ). (a <= t) < b is always true, if b is grater than 1.

SImplest conversion of your code would be:

#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <string>

using std::string;
using std::cout;

int main()
{
    const char* time = "173324"; 
    // note, that making it non-const is a not standard compliant

    char hold[3][3] = {};  // zero initialization

    for (int t = 0; t < 6;t++)
    {
        hold[t / 2][t % 2] = time[t];
    }


    string h(hold[0]);
    string M(hold[1]);
    string s(hold[2]);
    string datex = h + ":" + M + ":" + s;
    cout << datex;
    return 0;
}

Or maybe even so:

string hold[3];  
for (int t = 0; t < 6;t++)
{
    hold[t / 2] += time[t];
}
string datex = hold[0] + ":" + hold[1] + ":" + hold[2];

But better you should avoid making loops at all, provided string got constructor that receives iterators for beginning and end of source.

std::string h(time + 0, time + 2);
Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42
  • "you made assumption that if() checks every comparison inside its expression" there is no comparison that wont get checked in OPs code, its just their precedence that OP got wrong – 463035818_is_not_an_ai Sep 12 '18 at 09:05
  • @user463035818 there are languages were `if 0 < x < 2` means that x is greater than 0 and less than two. But C and consequently C++ do not use that syntax for obvious problems with implementation of it that would be "close-to-metal". It's not precedence , it's complete lack of understanding that C doesn't have _comparisons_. It have comparison operator that return boolean value. – Swift - Friday Pie Sep 12 '18 at 09:13
  • `0 < x` is a comparison and `(0 – 463035818_is_not_an_ai Sep 12 '18 at 09:15
  • @user463035818 two subsequent comparision operator calls, yeah. It's not a comparision though, which would be a predicate solution, not a boolean expression. Semantics. C\C++ do not work with predicates. – Swift - Friday Pie Sep 12 '18 at 09:17
  • sorry I dont get why you think `a < b` is not a comparison. Maybe I will do some reading later, but dont think we will converge here – 463035818_is_not_an_ai Sep 12 '18 at 09:19
  • @user463035818 because C++ semantics consider it being equal to a call of a function `bool operator<(int a,int b)`. That's not how OP was reading that notation though. – Swift - Friday Pie Sep 12 '18 at 09:23
  • maybe we can agree on this: "(a <= t) < b is always true, if b is grater than zero."... but if `b==1` and `(a<=t) == true` then `(a <= t) < b` is `false` – 463035818_is_not_an_ai Sep 12 '18 at 09:24
  • @user463035818 fruits of distraction – Swift - Friday Pie Sep 12 '18 at 09:28