1

The problem is that when you enter a name such as elvis (which has 5 letters), it will print this:

Please enter your name.
elvis
Your name is elvis
 and it is 6 letters long.
Press any key to continue . . .

the problem is that it makes another unnecessary line thats because after the elvis I pressed enter.

Sorry for being a new user , im new for these rules , please correct me and educate me , thanks for your time.

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

#define STR_LEN 7

int main(void)
{
    char name[10] = {0};
    printf("Please enter your name.\n");
    fgets(name ,10, stdin);
    printf("Your name is %s and it is %d letters long.\n" , name , strlen(name));
    system("PAUSE");
    return 0;
}
melpomene
  • 84,125
  • 8
  • 85
  • 148
Yuval
  • 180
  • 13

2 Answers2

4

fgets always writes that '\n' character at the end, if it fits (and, of course, sees it). So you need to manually remove it.

(I know because I've said it 20 times to my groupmates in University :/ )

You need to check if the last character is '\n' and, if so, remove it (overwrite with 0=='\0'). Some example code:

char str[256];
fgets(str, 256, stdin);
if (*str && str[strlen(str)-1] == '\n')
    str[strlen(str)-1] = 0;

(note that the above code assumes GCC optimizes pure function calls. If not you should save the length in a separate variable to optimize the program)

Paul Stelian
  • 1,381
  • 9
  • 27
  • 1
    ... which can be done with `name[strcspn(name, "\n")] = '\0';` – melpomene Jan 08 '17 at 17:48
  • Paul , my teacher said something about strcspn , I tried to manualy remove it , but unfortunatly it doesnt save the string without an \n , it will save it i.e 'elvis\n0' – Yuval Jan 08 '17 at 17:51
  • 2
    fgets doesn't always write a '\n' at the end. fgets will stop reading when it gets a '\n', but it can also stop for other reasons. For example here if what we enter surpasses 10 characters in length, fgets will stop and we will not have this '\n'. – Module Jan 08 '17 at 17:52
  • @Module It will write '\n' if it fits and it sees one. There will not be a '\n' at all in the read line if either the line is longer than 9 characters (remember the NUL terminator!) or it encounters EOF. – Paul Stelian Jan 08 '17 at 17:56
  • @Module And hence I said "you need to check [...] and, if so, remove it" – Paul Stelian Jan 08 '17 at 17:57
  • 1
    @PaulStelian I just saw where you wrote always rights [...] , if it fits. All good . – Module Jan 08 '17 at 17:58
  • @melpomene I don't actually get those functions. May you explain? – Paul Stelian Jan 08 '17 at 17:58
  • @PaulStelian I only used one function, `strcspn`. What's unclear about it? – melpomene Jan 08 '17 at 18:00
  • @melpomene The thing that I never got, neither in high school nor now at University, is what these extra functions are doing – Paul Stelian Jan 08 '17 at 18:02
  • 1
    @PaulStelian What "extra functions"? – melpomene Jan 08 '17 at 18:04
  • @melpomene I call them "extra" since I normally use only the more basic strlen, strcpy, strcat, strtok, strstr, str[r]chr. The others I don't remember and if I write code I would currently not use them – Paul Stelian Jan 08 '17 at 18:06
  • 2
    @PaulStelian Er. These functions are documented. You can just look it up in the manual (e.g. unix man pages). – melpomene Jan 08 '17 at 18:11
  • @PaulStelian -- I would up-vote your answer if you would add actual work code to strip off the (possibly) training newline – Soren Jan 08 '17 at 18:19
  • @Soren I usually allow the question OP to write the code himself, but sometimes it's useful to write it in the answer (after the "pseudocode"). Good point. – Paul Stelian Jan 09 '17 at 12:29
2

As how the fellow mates told you already, fgets gets chars from a file pointer(stdin in your case) adding to the name an extra '\n'. You can easly get rid of it writing something like

name[strlen(name)-1] = '\0';

Always format your printf its %lu not %d on strlen(name).

Also a good tip, please always check for errors in return of the function. Please, after posting here, always consult the linux man (fgets stdlib func), try some examples, debug them, search and read on google even on stack overflow you have a nice search option for it.(it's not hate, just a friendly general advice).

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

#define STR_LEN 7

int main(void)
{
    char name[10] = {0};
    printf("Please enter your name.\n");
    if (!fgets(name ,10, stdin)) {
        printf("Error reading from stdin");
        return 1;
    }

    size_t len = strlen(name);
    if (len > 0 && name[len-1] == '\n') {
        name[len-1] = '\0';
    }
    printf("Your name is %s and it is %lu letters long.\n" , name , strlen(name));
    system("PAUSE");
    return 0;
}

EDITED:(melpomene advice).

hoenir
  • 141
  • 2
  • 9
  • 3
    `name[strlen(name)-1]` is a bad idea. If `strlen(name)` happens to be 0, fun things will happen (OK, that can't happen in this particular case, but still). Also, if the user types 9 or more characters, this code throws one of them away (the last character of `name` is not guaranteed to be `'\n'`). – melpomene Jan 08 '17 at 18:13
  • melpomene, edited.I forgot that, thanks for pointing that out. – hoenir Jan 08 '17 at 18:25
  • 2
    `%lu` is the wrong format for `strlen()`, which returns a `size_t`, not an `unsigned long`. – melpomene Jan 08 '17 at 18:36
  • @melpomene size_t it's a typedef of unsigned long. http://tigcc.ticalc.org/doc/stddef.html – hoenir Jan 08 '17 at 18:37
  • 2
    Yes, on TIGCC: "*TIGCC is a C/ASM cross compiler for the TI-89, TI-92 Plus, and V200.*" I doubt that's what you're using. – melpomene Jan 08 '17 at 18:39
  • https://stackoverflow.com/questions/1089176/is-size-t-always-unsigned please, consult the third answer. So yeah, can we all decide that OP is using a normal platform like x86 with a standard compiler like gcc or some visual studio compiler. Com on it's not like OP is on a commodore 64 or smth. – hoenir Jan 08 '17 at 18:45
  • 1
    Yep, that says `size_t` is some unspecified unsigned integral type. I don't understand what your point is. – melpomene Jan 08 '17 at 18:47
  • 1
    I guess the deal with `size_t` is the MS runtime library - some (all?) versions of it don't support the `z` format modifier for `printf`, so you have to pretend that `size_t` is `unsigned long` or do explicit casting. I guessed MS here because of `system("PAUSE")` - this code is a symptom of programming in MS Visual Studio. – anatolyg Jan 08 '17 at 18:55