0

hopefully, you're able to help me put. I'm currently struggling with an exercise my university told us to do. I have to write a program in C which scans in a string and reads it through a function called read_name(). The program should output whether the entered string is correct or not. The conditions for the string are:

  • The first character should be an uppercase letter.
  • All the other characters in the entered string have to be letters
  • The minimum length of the string has to be at least 2 elements
  • The maximum length of the string has to be 20 elements

I already wrote the program and it executes finely, but everytime I enter a string, regardless if it contains only letters, numbers or symbols like a comma, it always ouputs that the entered string is incorrect. But I thought I already wrote the program in a way, so that every possible wrong input would be recognized but every correct input shoul be displayed as correct.

I think my mistake is in the for-loop in the function "int read_name(char input[])". I can't change the declaration of this function because it was predefined by my university. Everything else can be changed. :)

I hope I explained my problem clearly enough. Thanks a lot in advance.

Here's the code of the program:

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

#define MAX_STRING 20
#define MIN_STRING 2
#define UPPERCASE_MIN_ASCII 65
#define UPPERCASE_MAX_ASCII 90
#define LOWERCASE_MAX_ASCII 122
#define LOWERCASE_MIN_ASCII 97

int read_name(char input[]);

int main(void)
{
        char pre_input[MAX_STRING];
        char status;

        printf("Please put in a string: ");
        gets(pre_input);

        status = read_name(pre_input);

        if(status == 0) {
                printf("Input was incorrect!");
        } else {
                printf("Input was correct");
        }
        return 0;
}

int read_name(char input[])
{
        int i, n;

        n = strlen(input);

        if (n < MIN_STRING)
                return 0;

        if (input[0] < UPPERCASE_MIN_ASCII || input[0] > UPPERCASE_MAX_ASCII)
                return 0;

        for (i = 1; i <= n; i++) {

                if (input[i] < UPPERCASE_MIN_ASCII || input[i] > LOWERCASE_MAX_ASCII) {
                        return 0;
                } else if (input[i] > UPPERCASE_MAX_ASCII && input[i] < LOWERCASE_MIN_ASCII) {
                        return 0;
                }
        }
        return 1;
}

Alex

Xandi200
  • 23
  • 3
  • Don't use `gets`: https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used – UnholySheep Dec 03 '18 at 17:50
  • I tried scanf("%s", pre_input); but that didn't work either. – Xandi200 Dec 03 '18 at 17:52
  • And what do you see when you debug your code? Either using a debugger or printing helpful text should help you find the cause of your problem – UnholySheep Dec 03 '18 at 17:59
  • When I try using the comand-line arguments "-ansi -pedantic -Wall -Wextra" there is nothing that shows up. We're not allowed to use other debuggers, unfortunately. :( – Xandi200 Dec 03 '18 at 18:01
  • 1
    Those are compiler arguments, not a debugger. A debugger is a separate program that allows you to step through your code and see what it does. If your course really doesn't allow you to use debuggers demand a refund, debugging is the most important skill for programmers – UnholySheep Dec 03 '18 at 18:03
  • Oh sorry I mixed that up withe compiler arguments. I know it's ridiculous that they don't allow us to use a debugger. – Xandi200 Dec 03 '18 at 18:06
  • 2
    There are easier ways to express those limits — such as `#define UPPERCASE_MIN_ASCII 'A'` … `#define LOWERCASE_MAX_ASCII 'z'` — though many would simply use the character constants and not the long-winded macro names. Or you could use `islower()` or `isupper()` or `isalpha()` from the `` header. – Jonathan Leffler Dec 03 '18 at 18:23
  • Also, see [Why the `gets()` function is too dangerous to be used — ever!](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) The answers also discuss the alternatives available. – Jonathan Leffler Dec 03 '18 at 18:27
  • Even if you want or need to avoid parts of the standard libraries, you could still write your own `isalpha()`, `islower()` and `isupper()`. Then you could write your code so it's closer to a sentence-by-sentence translation of the requirements. – Tom Blodget Dec 04 '18 at 00:12
  • You have a second "off-by-one" error. Try a string with 20 letters. Hint: you don't have a big enough buffer for strlen to work properly. – Tom Blodget Dec 04 '18 at 00:14

2 Answers2

1
for (i = 1; i <= n; i++) 

It shall be i < n, because the nth element is the ending \0.

whfuyn
  • 153
  • 5
0

Yes the problem is with

for (i = 1; i <= n; i++)  // i<=n should be i<n

It brings the nth character of the input string (NUL character) into comparison logic of the loop and the ASCII value of NUL (Decimal 32) is outside the range of valid values.