1

I want to write some small program that is getting strings from the user(using console) when max input is 100 characters , and when user pressed enter - it will copy the input to some file. I want to exit the loop when user enters the string "exit"

for example : "hi how are you?" " bla bla" "exit" I just don't get how to make it work - should I use scanf? getchar? fgets?

char* buf ;
int i;


 buf = (char*)calloc(100, sizeof(char));
 while(1) 
  {
     fgets(s, sizeof(s), stdin);
     if (strcmp(s , "exit") == 0)
       break;
     else
   ...write to file...
   }

do I need manually put "\0" ?

thanks!

user1386966
  • 3,302
  • 13
  • 43
  • 72

3 Answers3

2

fgets() is fine, but in some implementations, it puts the trailing newline (\n) to the end of the line. You have to remove it in order the comparison to work, or prepare your comparison to accept both "exit" and "exit\n":

if (strcmp(s , "exit") == 0 || strcmp(s , "exit\n") == 0)
   break;

or

fgets(s, sizeof(s), stdin);
char *p = strchr(s, '\n');
if (p) *p = 0;

if (strcmp(s , "exit") == 0)
    break;

Sidenote: unless you intend to return the string to a caller function, there's no need for using calloc() at all. Use an automatic array instead:

char s[0x100]; // or whatever
  • thank you! another thing that I'm not quite sure- if I have an array and i want to place this string there- should I now go threw every letter and copy it : arr[i] = s[i] ? till I get to '\0' ? – user1386966 Apr 27 '13 at 16:07
  • @user1386966 Yes, but don't do that manually. `strncpy(dest, buf, destsize);`, but read the man page for `strncpy()` because it's not safe if you don't check its return value. –  Apr 27 '13 at 16:08
  • 1
    "Some implementations" being a superset of the conforming implementations, "No additional characters are read after a new-line character (**which is retained**)". If there is space (according to the size argument), `fgets` must store the newline in the buffer. – Daniel Fischer Apr 27 '13 at 16:17
  • @H2CO3 If I can guarantee that my destination is large enough to store the string (eg. I have subtracted `s` from `p` in your above examples, and the result is less than `sizeof dest`), then why would I want to use `strncpy`? – autistic Apr 27 '13 at 16:26
  • @undefinedbehaviour Then you don't, but I'm sure OP didn't make such a consideration. –  Apr 27 '13 at 16:28
2

should I use scanf? getchar? fgets?

Any of the above, but your while loop should translate to: while input is read, and the input isn't "exit". Your while loop currently translates to: while the world doesn't end.

I suggest something like:

while (fgets(s, sizeof s, stdin) == s && strcmp(s, "exit\n") != 0) {
    /* ... */
}

do I need manually put "\0" ?

No; careful selection of tools allows you to operate upon strings produced by the standard I/O library (in the case of the fgets/strcmp code above) using the standard string library, or upon non-strings by other more complex means.


PS. There is no need to cast malloc, and sizeof (char) is always one in C.

autistic
  • 1
  • 3
  • 35
  • 80
1

For your question, fgets() automatically appends a \0.

From C++ Reference:

A terminating null character is automatically appended after the characters copied to str.

Do note that fgets() stops reading at the press of Enter and appends a \n too, but, from your question, I gather that this might be favourable to you.

For the differences between fgets() and scanf(), a good discussion can be found here..

Community
  • 1
  • 1
Sukrit Kalra
  • 33,167
  • 7
  • 69
  • 71
  • @user1386966 Please don't leave the same comment under each answer. It's considered littering. –  Apr 27 '13 at 16:09
  • I get it that @H2CO3 already answered your question. It would be good if the discussions are centered in one area. Increases the readability ease for people visiting this thread in the future. – Sukrit Kalra Apr 27 '13 at 16:10