0

As a homework, I have to make a program which replaces all the words made of 3 letters with a "*".

For example:

input: cod is everything and I love it
output: * is everything * I love it 

Here is my program:

int main()
{
    char cuvant[101], final[101];
    char* pch;
    cin.get(cuvant, 100);
    pch = strtok(cuvant, " ");
    while (pch != NULL)
    {
        if (strlen(pch) == 3)
        {
            strcat(final, " *");
        }
        else
        {
            strcat(final, " ");
            strcat(final, pch);
        }
        pch = strtok(NULL, " ");
    }
    cout << final;
}

I don't get any error - but the output is blank. Also, the program doesn't exit with the code 0 (as it should be), it says "exited with code -1073741819". So obviously something is going on.

Am I using strtok/strcat wrong?

I feel like strcat can't be used in my case and this is the reason for the error, but I'm not sure. Am I right?

If so, how can I solve my problem?

Thanks.

Kalana
  • 5,631
  • 7
  • 30
  • 51
  • 5
    1. Use `std::string` 2. Use `+` to concatenate – AndyG Dec 19 '19 at 18:14
  • It would be a good start to ensure *valid* strings at the start (final is in an undefined state). Also, since C++, "just" stringstream? – user2864740 Dec 19 '19 at 18:14
  • 3
    Please choose between C and C++. I wish StackOverflow wouldn't let you select both. – AndyG Dec 19 '19 at 18:15
  • 2
    @AndyG I'm sorry - the reason I do that is because in class we are studying c++, but actually we are doing a lot of c-style things. Including using arrays of chars. I can't use std::string unfortunately. – Octavian Niculescu Dec 19 '19 at 18:17
  • @user2864740 how can they not be valid? – Octavian Niculescu Dec 19 '19 at 18:18
  • @JohnSmith The arguments go like this: on assignments requiring things done in C-ways, use *only* C. On assignments using/teaching C++, use C++. – user2864740 Dec 19 '19 at 18:18
  • 2
    `strcat` requires the destination to be a null-terminated char array. `char final[101]` declares an uninitialized array, so your call to `strcat` invokes undefined behavior – UnholySheep Dec 19 '19 at 18:18
  • 1
    Does this answer your question? [Why do i first have to strcpy() before strcat()?](https://stackoverflow.com/questions/18838933/why-do-i-first-have-to-strcpy-before-strcat) – Raymond Chen Dec 19 '19 at 18:18
  • @PaulMcKenzie it's not about money - this is how things are in my country. I'm in high school, and this is what we study. – Octavian Niculescu Dec 19 '19 at 18:20
  • Use **`return 0;`** at the end of the code , to remove Error : **program doesn't exit with the code 0** – Sayed Muhammad Idrees Dec 19 '19 at 18:20
  • @UnholySheep alright, this is by far the most useful answer. How can I solve my problem though? – Octavian Niculescu Dec 19 '19 at 18:20
  • @RaymondChen I'll look into it right now. Thanks. – Octavian Niculescu Dec 19 '19 at 18:21
  • Just a rather stupid remark about C/C++. I know they are different languages and lead to different codes. But it is still still common to give beginners some knowledge on both. I have often mixed C and C++ in the same program: each compilation unit using a single language but some being C and others C++. Rationales: legacy library or code usage, or very low level (hardware) programming where C is more appropriate, and C++ for the higher level constructs. But anyway mixing both libraries in same translation unit is indeed allowed per C++ but should be avoided if possible... – Serge Ballesta Dec 19 '19 at 18:24
  • 1
    When you see a program return a huge (or hugely negative) number like -1073741819, usually its the computer trying to tell you something. Convert it into hex (0xC0000005) to see if the code is more recognizable. Here is a list of [Magic Debug Numbers](https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_debug_values) that often, but not this time, help. – user4581301 Dec 19 '19 at 18:24
  • @SayedM.Idrees that's not required for C++ and C99 (or newer). In `int main` the `return 0;` is implicit. A non-0 return indicates that something else caused the program to terminate abnormally – UnholySheep Dec 19 '19 at 18:24
  • @SayedM.Idrees the program dies horribly long before it reaches a `return`. This code was automatically returned when the program crashed trying to access memory it did not own. – user4581301 Dec 19 '19 at 18:27
  • @user4581301 great answer. I knew that a code different than 0 means there's something wrong - but I didn't know that i need to conver it to hex. I just tried to search it online. – Octavian Niculescu Dec 19 '19 at 18:28
  • You're welcome. You don't always need to convert it to hex. It's just something to try when you don't recognize what a number means. – user4581301 Dec 19 '19 at 18:32
  • @JohnSmith -- I know that you're not allowed to use C++, but [see this](http://coliru.stacked-crooked.com/a/0a9f05f3ccc161a9) as an example. – PaulMcKenzie Dec 19 '19 at 18:47

5 Answers5

3

Your problem is that all the C-String functions expect your string to be null terminated (ie the character '\0' as the last character of a string.

The problem is that final is not initialized. It can contain any amount of raw garbage. So when you use strcat() it has to find the end (which could be anywhere).

The solution is to initialize final to make sure it is a zero length C-String.

 char cuvant[101];
 char final[101]  ={0}; // Fills the array with zero

Or.

 char final[101];
 final[0] = '\0'; // Make a C-String of length 0

Return code.

In C++ the return code is 0. But in C it is undefined (as you have no return statement). So you compiled your code with the C compiler not the C++ compiler.

An undefined value can be anything. The value -1073741819 is valid as anything.

Martin York
  • 257,169
  • 86
  • 333
  • 562
2

You need to initialize final

strcpy(final, "");

to make it null terminated before you start using it with strcat.

or just set

final[0] = 0;
user4581301
  • 33,082
  • 7
  • 33
  • 54
Totonga
  • 4,236
  • 2
  • 25
  • 31
1

try this for 'c'

memset( cuvant, 0, sizeof( cuvant )); 
memset( final, 0, sizeof( final ));
1

C++'s string extractors split input on whitespace; that can save you a bunch of parsing.

std::string word;
std::string result;
while (std::cin >> word) {
    result += ' ';
    if (word.length == 3)
        result += '*';
    else
        result += word;
Pete Becker
  • 74,985
  • 8
  • 76
  • 165
1

you can make the if statement looks like this :

if (strlen(pch) == 3)
    {
        strcat(final, "* ");
    }
    else
    {
        strcat(final, pch);
        strcat(final, " ");
    }

so the final string will not start by termination char.

walid barakat
  • 455
  • 1
  • 6
  • 17