2

I am trying to get an input by using scanf operator but I also needs its length, I can't define char name[number] because i don't know the size of the input that I get from the user...

Any ideas how to do it without using string.h?

This is what I tried to do but it is illegal since I define the length of the array:

char string1[30];
printf("Enter string1:");
scanf("%s",string1);
glglgl
  • 89,107
  • 13
  • 149
  • 217
KaramJaber
  • 851
  • 5
  • 13
  • 24
  • getline() is useful for that sort of thing. man getline() – Charlie Burns Nov 03 '13 at 20:21
  • You started to ask about the task of reading and the length you have there, but now you want to elaborate on `strcmp()`. Is it in `strcmp()` where you want the length test, or rather outside? That doesn't become so clear... – glglgl Nov 03 '13 at 20:56

2 Answers2

3

You can't possibly know how long the user's input string will be ahead of time. So you can only provide a buffer of some size, and hope that the input is shorter than that size; and if the input is too long, then your program will not get all of the input at once.

Suppose you are prompting the user for his/her first name. My first name is "Steve" so I only need 5 letters, but other names are longer. I just did a Google search for "longest first name" and one example I found was "Lydiakalanirowealeekundemondisha" which needs 32 letters. Okay, let's make the input buffer 128 letters long and figure it's probably long enough.

#include <stdio.h>

char first_name[128];

printf("Please enter your first name: ");
fgets(first_name, sizeof(first_name), stdin);

So here we are using fgets() to get the user input. We tell fgets() to store the input in our buffer (first_name) and we tell it the size of our buffer. NOTE: we are using the sizeof() operator here, so that the program will still be correct if someone edits the file and changes the size of the buffer.

Now, no matter what the user types in (or pastes in from the clipboard), our program will only read in the first 127 characters. If the user types in less than that, we get everything.

So now we can check to see how much we got:

if (strlen(first_name) >= sizeof(first_name) - 1)
{
    printf("That input is too long, sorry.\n");
}

Here we check to see how long the string actually was. If it was too long we give an error message to the user. In theory, the user could have typed exactly 127 characters and the input would fit exactly, but we have no way to know if the user typed exactly 127 characters or more than that. And in practice we don't expect a first name to be anywhere near that long, so it's safe to treat this condition as an error.

Now, here is how to not do it. Never do this ever.

char short_buffer[16];

printf("Please enter your first name: ");
gets(short_buffer);

The function gets() has no way to know how many characters will fit in the buffer. If the user types "Lydiakalanirowealeekundemondisha" then gets() will write off the end of the buffer and likely cause an error. Never use gets().

steveha
  • 74,789
  • 21
  • 92
  • 117
1

You probably won't get along without defining a maximum size.

It is not important not to define a size, but to know and respect it afterwards.

The easiest way to get input from a user is fgets():

char string1[50];
fgets(string1, sizeof string1, stdin);

Of course, you should check its return value.

If you want to accept (almost) any length, you can try the solution I gave here.

This is required to prevent an overflow of the given array. In order to work with the string, you can get its length wither with strlen(), or, if you are not allowed to use that or are walking to the strings nevertheless, by counting the characters until you hit a NUL byte.

The background of this is that strings in C are terminated by a NUL byte. They are sequences of chars, and the NUL byte (0, not '0' which would be 48) terminates this sequence.


If your only task is to verify that the strings you read are small enough, and complain if they aren't, then just do that :-)

int main(int argc, char ** argv)
{
    char string2[50]; // larger than required; in order to be able to check.
    char string1[30]; // if all is ok, you have maximum length of 29, plus the NUL terminator. So 30 is ok.
    char * ret = fgets(string2, sizeof string2, stdin);
    if (!ret) {
        fprintf(stderr, "Read error.\n")
        return 1; // indicate error
    }
    if (strlen(string2) >= sizeof string1) { // we can take this size as a reference...
        fprintf(stderr, "String 1 too long.\n")
        return 1; // indicate error
    }
    strcpy(string1, string2); // as we have verified that this will match, it is ok.
    // Otherwise, we would have to use strncpy.

    // Now read the 2nd string by the same way:
    ret = fgets(string2, sizeof string2, stdin);
    if (!ret) {
        fprintf(stderr, "Read error.\n")
        return 1; // indicate error
    }
    if (strlen(string2) >= sizeof string1) { // we can take this size as a reference...
        fprintf(stderr, "String 2 too long.\n")
        return 1; // indicate error
    }
    // Now we know that both strings are ok in length an we can use strcmp().
    int c = strcmp(string1, string2);
    printf("strcmp() result: %d.\n", c);
    return 0; // indicate success
}

I am not clear now if you are supposed to implement strcmp() as well. If so, I'll leave that as an exercise.

Community
  • 1
  • 1
glglgl
  • 89,107
  • 13
  • 149
  • 217
  • i have a task to implement the strCmp from the string.h and it is allowed a maximum size of 30, otherwise i have to print invauld message so i think that i have to know the length of the input to check legality – KaramJaber Nov 03 '13 at 20:28
  • @somebody This is a completely different thing. `strcmp()` has nothing to do with reading. If you try to imitate `strcmp()`, you must get the length of the given string by counting the characters until you hit the first NUL byte. – glglgl Nov 03 '13 at 20:34
  • what is required from us is to get 2 strings and they shall be less than 30, if not it is invaild so i have to keep there values and some variable – KaramJaber Nov 03 '13 at 20:51
  • @somebody It would be best if you would extend the question with the changed requirements you added to the comments, or even better start a new one. I could elaborate on `strcmp()` here now, but it wouldn't match so good to the question above. – glglgl Nov 03 '13 at 20:55
  • @somebody Ok. So you get 2 strings, you check their length and only then you compare. This is again something different which can be made fit here, so I'll try to write about that. – glglgl Nov 03 '13 at 20:57