0

For Example if I Input: 'stephen 8108' it outputs 'stephen' Instead of outputing 'stephen 8108'. Can someone help me out!

I want the full string to appear in the output. It reads the string only till the first white space. Even if i remove the for loop condition it doesn't seem to work it still reads only till the first white space.

#include<fcntl.h>
#include<stdio.h>
#include <unistd.h>
void main()
{
    char a[100];
    int i,f2,f3,f4;
    f2 = creat("a.txt",0666);
    f3 = open("a.txt",O_RDWR);
    printf("Enter your name & Roll-no\n");
    scanf("%s",a);
    for(i=0;a[i] != '\0';i++);
    write(f3,a,i);
    close(f3);
  }
stephen carvalho
  • 127
  • 1
  • 17
  • 4
    That's just how `scanf()` works. `%s` parses into a string until it finds whitespace. You might want to read my [beginners' guide away from `scanf()`](http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html) –  Aug 07 '17 at 07:27
  • there is issue with scanf. you should use some thing like scanf(" %[^\n]s", a). – rajesh6115 Aug 07 '17 at 07:27
  • 3
    @rajesh6115 just no. Use **either** `[]` **or** `s`. They are different conversions. –  Aug 07 '17 at 07:28
  • 1
    Unrelated to your problem, but the `creat` function creates and *opens* a file. It returns a file descriptor. You don't have to call `open` separately after. Because of this you have a *resource leak* as you don't close the `f2` descriptor (though it's done when the process ends). See [the manual pages on `open` and `creat`](http://man7.org/linux/man-pages/man2/open.2.html) for more information. – Some programmer dude Aug 07 '17 at 07:30
  • quick fix: `scanf("%s",a);` -> `scanf("%99[^\n]",a);`. But `scanf()` isn't the best tool for this and you should at least read a [scanf manual](http://man7.org/linux/man-pages/man3/scanf.3.html) –  Aug 07 '17 at 07:30
  • As for your loop, is it a requirement of your assignment? Because there's a nice standard C function called [`strlen`](http://en.cppreference.com/w/c/string/byte/strlen) that does exactly that. If there are standard functions, then use them. Don't reinvent the wheel. – Some programmer dude Aug 07 '17 at 07:32
  • Brother i dont think its duplicate as i want to know how to read till i encounter an return carriage in the for loop also. – stephen carvalho Aug 11 '17 at 17:10

3 Answers3

0

At the current state of your code, the for loop doens't have a body { ... } , so the write and the close operations would be executed only one time. Also if you want scanf to read a string with spaces you can use %[0-9a-zA-Z ] instead of %s

Gio G.
  • 21
  • 3
0

Regarding the input, there are at least two problems:

  • The s conversion of scanf() parses until it finds whitespace, it's documented that way.
  • Without a field width, scanf() will continue parsing when it doesn't find whitespace, overflowing your buffer -> undefined behavior.

The quick fix is to replace scanf("%s",a); with scanf("%99[^\n]",a);. But scanf() is definitely not the best tool to read input, it is for parsing. You seem to just want to read a whole line of input and there is already a function for that: fgets(). Use it in your example like this (include string.h if you want to use this method of stripping the newline character):

fgets(a, 100, stdin);
a[strcspn(a, "\n")] = 0; // remove the newline character if it was read by fgets
0

This is intended sprintf functionality. Cite: http://www.cplusplus.com/reference/cstdio/scanf/

Any number of non-whitespace characters, stopping at the first whitespace character found.

One option is to use the negated character matching (quoted from link above):

[^characters] Negated scanset

Any number of characters none of them specified as characters between the brackets.

For example, to match everything excluding a newline:

scanf("%[^\n]", a);

(Full working example below - although please don't take this as necessarily a full and perfect example of reading user input in C++...)

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

int main()
{
    char a[100];
    int fp;

    fp = open("a.txt", O_CREAT|O_WRONLY|O_TRUNC);

    printf("Enter your name & Roll-no\n");
    scanf("%[^\n]", a);

    write(fp, a, strlen(a));
    close(fp);
}

However: I would really encourage you to read the extensive warnings about buffer overflows: https://stackoverflow.com/a/1248017/817132

In short, make sure you don't allow the user to write beyond your (currently 100 character long) memory allocation.

wally
  • 3,492
  • 25
  • 31
  • Ty, that'll teach me to re-type than copy/paste! – wally Aug 07 '17 at 07:44
  • It's still confusing. Why are you talking about `sprintf`? And how do you "*adapt `%s`*"? You just use a different conversion instead. -- and HOW is this related to C++? It's C, not C++. –  Aug 07 '17 at 07:52