Hi guys can you please help me with this. All I need to do is input a number and display the corresponding alphabet.For example 2 then the output should be A B.. I am working on a code but my problem is the output is displaying together with a special character. Can you help me do it pls. Thanks in advance!

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
int main()
{
int num;
char *buffer;
printf("How long is the string:");
scanf("%s",&num);
buffer=(char *) malloc(num);
if (buffer==NULL) exit(1);
for(int i=0;i<num;i++)
{
for (int j=0;j<i;j++)
buffer[j]=(i%26)+'A';
printf("The strings are: %s \n",buffer);
getch();
free(buffer);
}
return 0;
}

Edited 4 Years Ago by gelaisg18

You have a number of problems in the code. Please be patient for a moment while I list them out.

'#include<conio.h>'

Use of this library should be avoided except in cases where it really does offer the best solution (which is extremely rarely).

printf("How long is the string:");

This prompt is not guaranteed to be displayed before scanf() blocks for input, so the user might be greeted by nothing more than a blinking cursor and no hint of what to do. The reason for that is C only guarantees three times when the output buffer gets flushed to the destination device (the screen in this case):

  1. When the buffer is full.
  2. When a newline character is sent.
  3. When fflush() is called on the output stream.

In the case of #1 you have no control over it because the size of the buffer and its current contents are unknown. #2 isn't ideal for prompts because then you'd have a prompt on one line and the blinkie cursor on the next line; it's kind of ugly. So the only option for prompts is using fflush:

printf("How long is the string: ");
fflush(stdout);

I'm flushing stdout because that's the stream object that printf writes to.

scanf("%s",&num);

num is not a string, you need to use the %d specifier. Also, it's critically important to check user input for failure. scanf() returns the number of successful conversions, which in general if that number corresponds to the number of specifiers you used denotes complete success. In this case any return value other than 1 means scanf() failed. So you'd do something like this:

printf("How long is the string: ");
fflush(stdout);

if (scanf("%d", &num) == 1) {
    /* success, work with num */
}

buffer=(char *) malloc(num);
if (buffer==NULL) exit(1);

This is actually fine syntactically and semantically, kudos. :) My only nits would be that 1 isn't a portable argument for exit(), and return instead of exit() is conventional for terminating the program from main(). The three portable options are:

  1. 0 - This always works, and means success.
  2. EXIT_SUCCESS - This corresponds to 0, and is a macro defined in stdlib.h.
  3. EXIT_FAILURE - This has an implementation dependent value and is a macro in stdlib.h.

EXIT_SUCCESS is presumably there as a counterpart to EXIT_FAILURE, and in general I suggest that for consistency you use EXIT_SUCCESS as your return value instead of 0 when you're also using EXIT_FAILURE somewhere. So something like this:

int main(void)
{
    ...

    buffer = malloc(num);

    if (buffer == NULL)
        return EXIT_FAILURE;

    ...

    return EXIT_SUCCESS;
}

Eventually someone will also tell you that the cast on malloc() isn't required and can also hide the very legitimate error of forgetting to include stdlib.h. However, it's not uncommon to write C that must also compile as C++ and it's a well known issue, so I don't consider casting malloc() to be a significant risk anymore. Just be aware of it. :)

I'll also mention that when allocating memory for a string, failure to add 1 extra character for the terminating '\0' raises red flags for me. Sometimes that extra character is included in the total, but most of the time it's not and represents an error. In this case you need to add 1 to your total.

buffer[j]=(i%26)+'A';

In theory this code is not portable, but in practice it's likely to not be an issue. The problem is that some character sets (EBCDIC in particular) don't have the latin alphabet in contiguous spots. Other characters are mixed in, so this line would certainly produce funky output. However, you're likely to be using either some variant of ASCII or Unicode, both of which do make the guarantee that the latin alphabet is contiguous by value.

printf("The strings are: %s \n",buffer);

You neglected to terminate your string with '\0'. So while you avoided the problem of not having enough memory, printf() will now overrun the buffer and print anything it sees until it finds a null character somewhere out in the nether regions of memory. That's probably the issue you're having at the moment.

getch();

Try to avoid getch(). Most of the time the standard getchar() is a suitable replacement.

free(buffer);

Awesome, you remembered to release your memory. :) But it's in the wrong place. The next iteration of the outer loop will use the freed pointer. This line should be moved to just before you return.

Now for the logic part of this reply. I don't really like your solution because it generates the alphabet instead of simply printing a segment of an existing alphabet. Also, what happens if num is greater than the length of the alphabet?

I think a better solution would be to define an explicit alphabet, thus avoiding the portability problems of the character set, and then use a wrapping index so that for large values of num the loop will just start over from the beginning of the alphabet. Something like this:

#include <stdio.h>
#include <string.h>

int main(void)
{
    const char *alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    size_t len = strlen(alphabet);
    int num;

    printf("How long is the string: ");
    fflush(stdout);

    if (scanf("%d", &num) == 1) {
        for (int i = 0; i < num; ++i)
            printf("%-2c", alphabet[i % len]);

        puts("");
    }

    return 0;
}

Another added benefit is that you no longer need dynamic memory, with its performance overhead and sometimes tricky semantics.

Hi Sir Deceptikon.. thanks for a very informative reply.. ^^ it works well! You are great! godbless!

This question has already been answered. Start a new discussion instead.