0

I am trying to create a reversed string using getchar() to first read a string in array format. I did not write the reversing part yet. The code works for any strings without space. Ex. "HelloWorld!" will output "HelloWorld!" but "Hello World!" will only output "Hello".

#include <stdio.h>

#define MAX_SIZE 100

int main() 
{
    char temp;
    char my_strg[MAX_SIZE];
    int length;

    printf("Please insert the string you want to reverse: ");
    scanf("%s", my_strg);

    while((temp = getchar()) != '\n')
    {
        my_strg[length] = temp;
        length++;
    } 

    printf("%s\n", my_strg);

    return 0;
}
6
  • 3
    length is uninitialized, so my_strg[length] is likely to be out of bounds. Commented Jan 28, 2020 at 15:42
  • 2
    Is the scanf call left over from an earlier version of the code and you forgot to remove it? Commented Jan 28, 2020 at 15:45
  • You use scanf to read the first string (up to whitespace), and then you iterate over the rest of the input, ....why? Assuming you did initialize length to zero, you would now be overwriting the string read by scanf. Since you did not initialize length, this is just UB, but even if you did it's not at all clear why you're doing this. Commented Jan 28, 2020 at 15:56
  • Initialize int length = 0;, get rid of scanf("%s", my_strg); (it is superfluous) , change to while(length < MAX_SIZE - 1 && (temp = getchar()) != '\n' && temp != EOF) add my_strg[length] = 0; before printf("%s\n", my_strg); to nul-terminate. (or in the alternative initialize char my_strg[MAX_SIZE] = "";) Commented Jan 28, 2020 at 16:11
  • 1
    In addition to what @DavidC.Rankin wrote, char temp; should be replaced with int temp; because the value EOF might not fit in a char. Commented Jan 28, 2020 at 18:05

3 Answers 3

2

Your program has undefined behaviour, since you are attempting to access an element of an array, my_strg[length] with an unitialized value of length.

To fix this, move your declaration of length to after the scanf call and initialize it to the length of the string that scanf reads:

scanf("%s", my_strg);
size_t length = strlen(my_strg);

Alternatively, drop the scanf call completely and initialize length to zero:

    char my_strg[MAX_SIZE] = { 0, }; // Note: make sure you ALSO initialize your array!!
    printf("Please insert the string you want to reverse: ");
    size_t length = 0;
    while ((temp = getchar()) != '\n') {
    //..

Note: If you (for some reason) don't want to initialize your entire array to zeros (as the first line in my second code block will do), then make sure to add a zero (nul) character at the end of the string, before printing it (or doing anything else with it). You could simply add this line after the while loop:

    my_strg[length] = '\0'; // "length" will already point to one-beyond-the-end

EDIT: To address the very good points made by David C. Rankin in the comments section, you could (should) improve your while loop control to: (a) prevent buffer overflow and (b) handle input error conditions. Something like this:

while ((length < MAXSIZE - 1) && (temp = getchar()) != '\n' && temp != EOF) {
    //..

but the exact tests and controls you use would depend on how you wish to handle such issues.

Sign up to request clarification or add additional context in comments.

1 Comment

What if a 120-char string is entered? What if Ctrl+d is pressed to terminate input? Your initialization is correct, but can also be char my_strg[MAX_SIZE] = ""; which makes the use as a string apparent.
2

Your issue is scanf. scanf only reads until whitespace is encountered. To fix this, you can use fgets (and strcspn to remove the newline):

if(fgets(my_strg, sizeof(my_strg), stdin) == NULL)
{
    perror("fgets");
    return EXIT_FAILURE;
}
my_strg[strcspn(my_strg, "\n")] = '\0';

Or with scanf...

if(scanf("%99[^\n]", my_strg) != 1)
{
    fprintf(stderr, "scanf() failed to read\n");
    return EXIT_FAILURE;
}

After these changes you can entirely remove your getchar loop.

In your program you need to check for I/O errors. I've shown you how to do this above. If you don't do this, your program could give incorrect output or in certain cases cause undefined behavior (which usually results in a crash).

Bonus: here's how to reverse a string:

size_t l = strlen(my_strg) / 2;
char *s = my_strg, *e = s + l;
while(l--)
{
    char tmp = *--e;
    *e = *s;
    *s++ = tmp;
}

2 Comments

A stern scolding for the OP failing to check the return of the user input function would also be informative and good examples of the proper way to validate the return of fgets() and scanf() helpful. (it seems he is missing that concept). Very good choice with fgets(). Always driving home the point that you cannot properly use any user input function without checking the return helps cement the learning for new C programmers.
@DavidC.Rankin Sure. There you go.
1

By definition, scanf("%s", my_strg) reads a string until the first white space (and a blank counts as white space). So "Hello world" will be read until the first blank, i.e. my_strg will contain "Hello" then. To read until a new line (including the newline), use fgets.

BTW: variable length is uninitialized, such that you get undefined behaviour.

3 Comments

The OP seems to know that scanf doesn't read the entire line … that's what the following getchar loop is for.
I just removed the entire scanf line and the code seems to work fine for any strings over 8 char long. If it is less than 8 char the rest of the string is printed as random symbols e.g. "A" is printed as "A©?ïvý■`"
That's because you have both length and your my_strg array unitialized - so there will be pseudo-random data in those variables, and anything can happen (undefined behaviour).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.