0

Hi I want to write a program which takes a string and a number as input and then shifts the elements of string by given number, and also the string is always capital letters and the output should only be capital letters too
example 1 : -1 , "AB CD" output 1 : "ZA BC" example 2 : +3 , "ABC" output 2 : "DEF" I have written this code but if there is a space in my string , the program doesnt work properly for example : -1 "AA AA" the output is : "ZZ" But i was expecting "ZZ ZZ"

int main()
{
    char str[100] = {NULL},y;
    int n,x,i=0;
    scanf_s("%d", &n);
    scanf_s("%s", str);
    while (str[i] != NULL) {
        x = str[i];
        if (x + n >= 65 && x + n <= 90) {
            y = x + n;
            str[i] = y;
        }
        else if (x + n < 65) {
            while (x + n < 65) {
                x += 26;
            }
            y = x + n;
            str[i] = y;
        }
        else if (x + n > 90) {
            while (x + n > 90) {
                x -= 26;
            }
            y = x + n;
            str[i] = y;
        }
        i++;
    }
    printf("%s", str);
    return 0;
}
Oka
  • 23,367
  • 6
  • 42
  • 53
agent007
  • 1
  • 1

1 Answers1

1

After reading non-whitespace, the scanf specifier %s stops when it encounters whitespace.

Instead of "%s", use " %99[^\n]" to:

  • read and ignore leading whitespace, then
  • read up to 99 characters, or until a newline character is encountered.

Reading at most 99 characters is important, as you must leave room in your buffer for the null-terminating byte, and not limiting the amount of data read can easily lead to buffer overflows.

The return value of scanf_s should be checked to ensure the expected number of conversions took place, before any data is used.

if (1 != scanf_s("%d", &n))
    /* error! */;

Note that scanf_s requires a secondary argument when using %s or %[, which is the size of the buffer

char buf[10];
if (1 != scanf_s("%9s", buf, (rsize_t) sizeof buf))
    /* error! */;

which is supposed to be of type rsize_t. If you are using the MSVC versions of these functions, this type is unsigned.


Due to the pitfalls involved with using scanf properly, and the portability issues of scanf_s, consider instead using fgets to read lines of input (and strtol to parse an integer).

For clarity, consider using character constants like 'A' and 'Z', instead of integer constants like 65 and 90.

As is, your current code does not account for non-alphabetic characters, and will shift those. Consider the use of isalpha or isupper to filter the application of the shift.

Note NULL is usually considered a pointer value. Use '\0', or just 0, to represent the null-terminating byte.

Oka
  • 23,367
  • 6
  • 42
  • 53