tags:

views:

68

answers:

3

Hi, this program accepts user input and saved to a char array. Then creates a file and put those texts to the new file. Problem is, it can only copy the part before space. Current Output : "how to read" --> "how"

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argv, char *argc[]){
    int fd;
    char buffer[100];

    printf("Type your text : ");
    scanf("%s",&buffer);

    fd=open("menew.txt",O_CREAT|O_WRONLY|O_EXCL,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
    if(fd<0){
        printf("file already exist!\n");
        }else printf("file created!\n");

    fd=write(fd,buffer,20);
    if(fd<0){
        printf("error on writing...\n");
        }else printf("successfully written!\n");

    close(fd);
    return 0;
}
+5  A: 

The problem isn't with the writing, it's with the reading -- the scanf %s conversion skips any leading whitespace, then reads and converts up to (but not including) the next white space.

You probably want to use something like fgets or the %[^\n] conversion with scanf.

Edit: I should probably also mention that when/if you use the scanset conversion (%[^\n]), you should specify the length of buffer you're reading into.

As far as the &buffer in scanf("%s", &buffer); being an error, technically it does give undefined behavior, but in reality I don't know of any implementation where it makes a real difference.

In this case, buffer was defined as an array, not a pointer. The name of an array "decays" to a pointer under many circumstances, but not when used as the operand of the address-of operator (unary &). As such, buffer and &buffer yield exactly the same result, the address of the beginning of the array.

There is still a difference though. When you use just buffer, you get a value with the type pointer to char (given that buffer is an array of char). When you use &buffer, you get a pointer of the type pointer to array of MAXLEN char.

Now, when you pass a value to scanf (a variadic function), you get undefined behavior when/if the type of the value you pass does not match the type expected by the conversion you specified. In reality, with every C compiler I've ever heard of, it'll work fine though, because the same address will be passed either way. In theory (but only in theory, AFAIK) a compiler could use some sort of "fat pointer" that included type information along with the address, so scanf would be able to detect the type mismatch. In reality, I don't know of any compiler that does anything very similar, so you won't see any difference between using just buffer and using &buffer in this case.

In other circumstances, however, the difference can be detectable. Addition and subtraction on pointers is based on the type, so (for example) array+1 and &array + 1 will yield different results:

#include <stdio.h>

int main() { 
    char array[10];

    printf("%p %p %p\n", array, array+1, &array+1);
    return 0;
}

This will print three numbers. The first number will be some arbitrary number, typically in hexadecimal. The second will be one greater than the first, and the second will be 10 greater than the first (because I defined it to be an array of 10 characters...)

Jerry Coffin
Thanks for your information. I'll keep in mind them. For my problem, I find out that gets(buffer) solved.
Devyn
**Please** forget that you ever even heard of `gets()`, and use `fgets()` instead. There is simply no reasonable excuse for using `gets()` -- ever!
Jerry Coffin
A: 

At least one error:

scanf("%s",&buffer);

should be:

scanf("%s", buffer);

You were taking the address of a pointer. Probably not what you had intended.

Edit:

scanf also has the limitation described by Jerry Coffin.

luke
A: 

Finally I found the solution!!! Use gets(buffer); instant of scanf("%s",&buffer);

Devyn
Never use `gets`. Use `fgets` instead. `gets` doesn't check for buffer overruns, and thus cannot be used safely in this case.
Alok
Thanks, I'll try out! :)
Devyn