garbage values being printed out

Pages: 12
Dec 1, 2017 at 3:17pm
so I made a quick algorithm to check for duplicates and if it's detected don't add them to a new string,basically finding every letter in a string

the algorithm looks solid to me but when I print it out I get this he@l°_´v

where the heck is the @ and the other strange characters coming from?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 void check(const char* str,int size){

     char newstr[size+1];
     int newSize;
     bool duplicate = false;

      for(int i = 0; i < size-1; i++){

        for(int j = i+1; j< size; j++){

        if(str[i] == str[j]){
            duplicate = true;
            break;
         }

        }

        if(!duplicate){
           newSize++;
           newstr[i] = str[i];
         }
         duplicate = false;

      }

      cout << newstr << endl;
}


int main()
{
    char str[] ="hello";
    check(str,5);

    return 0;
}
Dec 1, 2017 at 3:27pm
c-strings are terminated with a null character terminator '\0'
Dec 1, 2017 at 3:33pm
thanks ne

I thought that a \0 would be added on automatically

also how in earth is hello being printed twice,I'm starting to think it's codeblocks rather than my fault

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

int main()
{
    char str[] ="hello";
    // check(str,5);
    char str2[5];

    for(int i = 0; i < 5; i++){

        str2[i] = str[i];
    }

    cout << str2 << endl;

    return 0;
}





this prints hello twice,even though it only has five chars or bytes how is that even possible? :s
Last edited on Dec 1, 2017 at 3:39pm
Dec 1, 2017 at 3:39pm
also I added a null terminating char it seems to print 5 letters now but it still prints some garbage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

void check(const char* str,int size){

     char newstr[size+1];
     int newSize;
     bool duplicate = false;
     int k = 0;

      for(int i = 0; i < size-1; i++){
        k++;
        for(int j = i+1; j < size; j++){

        if(str[i] == str[j]){
            duplicate = true;
            break;
         }

        }

        if(!duplicate){
           newSize++;
           newstr[i] = str[i];
         }
         duplicate = false;

      }
      k++;
      newstr[k] = '\0';

      cout << newstr << endl;
}


int main()
{
    char str[] ="hello";
     check(str,5);


    return 0;
}




he@l°

any idea why?

thanks
Dec 1, 2017 at 4:04pm
I changed the code a bit and still getting garbage values out

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

void check(const char* str,int size){

     char newstr[size+1];
     int newSize;
     bool duplicate = false;
     int k = 0;
     int i = 0;

      for(i; i < size-1; i++){
        k++;
        for(int j = i+1; j < size; j++){

        if(str[i] == str[j]){
            duplicate = true;
            break;
         }

        }

        if(!duplicate){
           newSize++;
           newstr[i] = str[i];
         }
         duplicate = false;

      }
      i++;
      int b = 4;
      while(b > 0){

        if(str[i] == str[b]){

           duplicate = true;
           break;
        }

        b--;
      }
      if(!duplicate){

        newstr[i] = str[i];
      }

      k++;
      newstr[k] = '\0';

      cout << newstr << endl;
}





he@l°
Dec 1, 2017 at 4:09pm
any idea why?

Probably because you're adding the termination character at the wrong place in the string. You would be better off terminating the string each time you add a character to the string.
1
2
           newstr[i] = str[i];
           newstr[i + 1] = '\0';

Another option would be to initialize the string to all zeros.

By the way your program really shouldn't compile because you're using a Variable Length Array which is not allowed in C++. Array sizes must be compile time constants.

Why are you using two loops? what you appear to be trying to do can be accomplished with one loop.


Last edited on Dec 1, 2017 at 4:11pm
Dec 1, 2017 at 4:19pm
Hi Jlb

I used two loops because I can't figure out a way to test if the last character is a duplicate,since the for loop stops executing when i = 3 the last value never gets compared with the rest of the string,

also what do you mean by variable length array?

so you can't have char array[n] ? how come?

I know you can it when declaring arrays on the heap such as int *array = new int[n];



thanks
Last edited on Dec 1, 2017 at 4:25pm
Dec 1, 2017 at 5:02pm
also what do you mean by variable length array?

An array with a run time size. IE:

1
2
int size = 10;
int array[size]; // This is a VLA. 


so you can't have char array[n] ? how come?

Correct if n is not a compile time constant. Because the C++ standard states that array sizes must be compile time constants.

I know you can it when declaring arrays on the heap such as int *array = new int[n];

That is correct. However the better option would be to use std::string instead of C-strings and std::vector for most other arrays.

I used two loops because I can't

What exactly are you trying to accomplish? Are you trying to "remove" all duplicate characters or are you trying to populate your "new" string with only the non-duplicated characters, or are you trying to populate the "new" string with only unique characters???



Dec 1, 2017 at 5:44pm
thanks jlb just one quick follow up how come you cam do it when declaring arrays on the heap but have to be compile time constants on the stack?

also I'm trying to find if duplicates of a letter exist in a string then display the letters

and yes trying to populate the new string with unique characters

but trying to remove duplicates would be the ideal situation without creating a new array
Last edited on Dec 1, 2017 at 5:45pm
Dec 1, 2017 at 6:22pm
just one quick follow up how come you cam do it when declaring arrays on the heap

The C++ standard doesn't allow creating statically allocated arrays on either the heap or the stack with run time sizes. When you use "new" you are manually allocating the memory and you can use non-run time sizes. But now you, the programmer, are responsible for deleting the memory when it is no longer needed and if you forget to properly delete the memory you will have a memory leak.

also I'm trying to find if duplicates of a letter exist in a string then display the letters

Are you trying to find all duplicates or just adjacent duplicates?

and yes trying to populate the new string with unique characters

So what do you consider unique characters? If your source word is "hello" would the resulting "unique" string be "helo" or "heo". Also consider something like "unique" what would the resulting string contain?
Dec 1, 2017 at 6:39pm
I never knew that,Is that allowed in java? but how come my code runs and compiles with no issues?

and yes it did print heo but I wanted it to print helo,I kind of found an algorithm that works,it does actually print only a character once but it displays it in the wrong order

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58


void check(const char* str,int size){

     char newstr[size+1];
     int newSize = 0;
     bool duplicate = false;
     int k = 0;
     int i = 0;

      for(i; i < size-1; i++){
        k++;
        for(int j = i+1; j < size; j++){

        if(str[i] == str[j]){
            duplicate = true;
            break;
         }

        }

        if(!duplicate){

           newstr[newSize] = str[i];
           newstr[newSize + 1] = '\0';
           newSize++;
         }
         duplicate = false;
      }

      cout << i << endl;
      int b = i-1;
      while(b > 0){

        if(str[i] == str[b]){

           break;
        }
        b--;
      }

        newstr[newSize] = str[i];
        newstr[newSize + 1] = '\0';
        cout << newstr << endl;
}



int main()
{
    char str[] ="blob";
    int size = sizeof(str) / sizeof(char);
    check(str,size-1);

    return 0;
}



outputs lob instead of blo
Dec 1, 2017 at 6:53pm
I kind of found an algorithm that works,it does actually print only a character once but it displays it in the wrong order

You do know that you will learn more by writing your own code instead of "finding" code from unknown sources.

Dec 1, 2017 at 6:57pm
I wrote it myself but as I said it doesn't print them in order such as blob it prints lob instead of blo

I should have choosen my words better lol I
Dec 1, 2017 at 7:12pm
adam2016 wrote:
how come my code runs and compiles with no issues?

Apparently you're using a compiler that both supports this non-standard language extension and doesn't warn you that you're using it and that your program won't work in another compiler.

Your code fragment does not compile when I try to use it:

MSVC 2017 says

consoleapplication1.cpp(6): error C2131: expression did not evaluate to a constant
consoleapplication1.cpp(6): note: failure was caused by non-constant arguments or reference to a non-constant symbol
consoleapplication1.cpp(6): note: see usage of 'size'


g++ -pedantic-errors says (https://wandbox.org/permlink/K6aN2K3u07wjuSOy):
prog.cc: In function 'void check(const char*, int)':
prog.cc:6:24: error: ISO C++ forbids variable length array 'newstr' [-Wvla]
      char newstr[size+1];
                        ^

clang -pedantic-errors says (https://wandbox.org/permlink/KLuNsivg4vLhYWvC):
prog.cc:6:17: error: variable length arrays are a C99 feature [-Werror,-Wvla-extension]
     char newstr[size+1];
                ^
prog.cc:22:12: warning: variable 'newSize' is uninitialized when used here [-Wuninitialized]
           newSize++;
           ^~~~~~~


Note I had to supply -pedantic-errors to gcc and clang, since those compilers require that commandline option to use portable C++.

Also, don't overlook this comment:
jlb wrote:
the better option would be to use std::string instead of C-strings and std::vector for most other arrays.

I'd say you have no business touching arrays at all until you're comfortable using strings and vectors (and good textbooks follow that order, too)
Dec 1, 2017 at 7:18pm
thanks guys never knew that =)

is this the same for other languages such as Java?
Dec 1, 2017 at 7:21pm
Is what the same?

Dec 1, 2017 at 7:25pm
that arrays can't have run time variables to decide how big they are
Dec 1, 2017 at 7:36pm
What difference does it make, you're writing C++ programs not Java programs and in C++ array sizes must be compile time constants.

By the way arrays in Java are objects, which would be the same as a class in C++. And all Java arrays are dynamically allocated, I don't think it is even possible to manually allocate memory in Java.

Dec 1, 2017 at 7:51pm
good point thanks jlb,sorry for asking so many questions just wondering would there be a better way of doing what I'm trying to do but using one loop? you said I could use one loop but this will only check up to the [size-1] element,in my example I then use another while loop to test for duplicates with the last character,is this ok or would you go about another way,

thanks
Last edited on Dec 1, 2017 at 8:00pm
Dec 1, 2017 at 8:03pm
you said I could use one loop but this will only check up to the [size-1] element

That was because your problem statement wasn't very clear (to me anyway). To do what you now appear to want will require multiple loops.

But really you should also be considering functions, and as I said earlier, you should be using std::string not the horrible C-strings.


Last edited on Dec 1, 2017 at 8:03pm
Pages: 12