4
char copy, array[20]

    printf("enter ..."):
    scanf("%s", array);

    if (strlen(array) > 20 ) 
      { 
       strcpy(copy, array....); 

what would I need to do to make it only grab the first 20 character if the input is more then 20 character long

3
  • 1
    What is that supposed to mean? copy is not an array at all. array is 20 characters long. It array simply cannot be longer that 20 characters. Commented Feb 25, 2011 at 21:32
  • you overflow with scanf if you enter more than 20bytes. Look at fgets. Commented Feb 25, 2011 at 21:35
  • @James strncpy doesn't necessarily NUL-terminate the result -- it's almost never what one wants (its original purpose was to copy UNIX directory entries, which fit in 14 bytes and were NUL-terminated if shorter). In any case, it isn't applicable here. Commented Feb 28, 2011 at 9:12

7 Answers 7

5
char array[20+1];
scanf("%20s", array);

Problem solved.

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

4 Comments

+1 for solving the problem at source, although I would prefer fgets.
@Zach – fgets would retain '\n'.
@Zach @aaz Except for in the case where the array was greater than 20, which means you'd also have to add logic to see whether or not it did retain the '\n' and replace as appropriate. But on the flip side of the coin, with scanf you have to specify the size of the buffer twice (you can't pass an integral type to the scanf specifier for the width except with platform-specific extensions, so you have to specify it once as an integer when declaring the array and again in a string for the scanf specifier [or do something ugly like snprintf(spec, sizeof(spec), "%d%%s", sizeof(buf));])
@user470379 – You could use a preprocessor macro for the buffer size and paste it into the format string, that would be reasonably neat. But, regardless, they are conceptually not interchangeable: fgets gives physical lines (and you would typically want to malloc a larger buffer on failure), scanf("%s") gives logical names (trimmed, no internal whitespace, probably limited in length by semantics).
3

Your question is not clear, since the code makes little or no sense. Your input cannot be longer than 20 characters since the receiving array is only 20 characters. If the user inputs more, your program will produce undefined behavior. So, the main problem here is not limiting the copy, but rather limiting the input.

However, your question seems to be about limited-length string copying. If that's what you need, then unfortunately there no dedicated function in standard library for that purpose. Many implementation provide the non-standard strlcpy function that does exactly that. So, either check if your implementation provides strlcpy or implement your own strlcpy yourself.

In many cases you might see advices to use strncpy in such cases. While it is possible to beat strncpy into working for this purpose, in reality strncpy is not intended to be used that way. Using strncpy as a limited-length string copying function is always an error. Avoid it.

18 Comments

If strncpy is not intended to be used for this, what do you think it is for?
@Zack: You can read about it in Wikipedia or here: stackoverflow.com/questions/2884874/… . Basically, strncpy is not a zero-terminated string function at all and its name is just a misnomer. It is just a historical blunder that lives on in the standard library.
I would appreciate a pointer to an actual primary source for your assertion that strncpy was "created to fill 14-character long file name fields in one archaic version of Unix file system." I don't see it in either of the places you point to.
Addendum: your assertion is backed up by C99 Rationale §7.21.2.4, but that's not a primary source either, and the C committee has been known to get things horrifically wrong.
@Zack: Well, for a programmer of my generation, this is like trying to remember the first fairy-tale I read. Let's just say I heard about it Mr. Ritchie himself in one of his interviews (I do remember that he did talk about it), although there were many other sources. It is just something to memorize: strncpy was originally introduced for filling out 14-char file name fields in some old Unix filesystem.
|
1

Use strncpy instead of strcpy. That's all there is to it. (Caution: strncpy does not nul-terminate the destination string if it hits its limit.)

EDIT: I didn't read your program carefully enough. You lose already at the scanf call if user input is longer than 20 characters. You should be calling fgets instead. (Personally I think *scanf should never be used - this is only the tip of the iceberg as far as problems they cause.) Furthermore, copy has room for only one character, not twenty; but I'm going to assume that's a typo on your part.

2 Comments

Why do you not like scanf?
@cokedude 1) Depending on the format string, it can be just as dangerous as gets (as this question demonstrates); 2) numeric overflow triggers undefined behavior, i.e. scanf("%d", &x) is allowed to crash if the user types too many digits; 3) writing a parser that's robust in the face of malformed input is easier if you don't use scanf.
1

Alternatively, you don't need to use strcpy to read just 20 characters (and you won't have to include strings.h):

char c;
for( i = 0; i < 20; i++ ) {
    c = getchar();
    if (c != '\n') array[i] = c;
    else break;
}
array[i+1] = '\0';

Don't forget to declare array as char array[21] to make sure '\0' will be included.

Comments

0
 strncpy (copy, array, 20);

does the trick. Exxcept the string would NOT be null-terminated if it was >20 chars!

http://www.cplusplus.com/reference/clibrary/cstring/strncpy/

Comments

0

Use strncpy. Make sure to null terminate the destination.

Comments

0

You need to change your scanf() call, not your strcpy() call:

char copy[20], array[20];
printf("enter....");
scanf(%20s",array); // read a maximum of 20 characters
strcpy(copy, array);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.