此程序接受用户输入并保存到char数组。然后创建一个文件并将这些文本放到新文件中。问题是,它只能在空间之前复制零件。 电流输出:“如何阅读” - > “怎么样”
#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;
}
答案 0 :(得分:5)
问题不在于写作,而在于阅读 - scanf
%s
转换会跳过任何前导空格,然后读取并转换为(但不包括)下一个空白区域
您可能希望使用fgets
或使用%[^\n]
进行scanf
转换。
编辑:我可能还应该提一下,当你使用扫描集转换(%[^\n]
)时,你应该指定你正在读取的缓冲区的长度。
至于&buffer
中的scanf("%s", &buffer);
是一个错误,从技术上来说它确实给出了未定义的行为,但实际上我并不知道任何实现它会带来真正的差异。
在这种情况下,buffer
被定义为数组,而不是指针。在许多情况下,数组的名称“衰减”到指针,但当用作地址运算符(一元&
)的操作数时,不。因此,buffer
和&buffer
会产生完全相同的结果,即数组开头的地址。
但仍然存在差异。当您仅使用buffer
时,您将获得类型为pointer to char
的值(假设缓冲区是char数组)。使用&buffer
时,会得到类型为pointer to array of MAXLEN char
的指针。
现在,当您将值传递给scanf(一个可变参数函数)时,如果您传递的值的类型与您指定的转换所期望的类型不匹配,则会得到未定义的行为。实际上,对于我听说过的每一个C编译器,它都可以正常工作,因为相同的地址将以任何一种方式传递。理论上(但仅在理论上,AFAIK)编译器可以使用某种“胖指针”,其中包含类型信息和地址,因此scanf
将能够检测到类型不匹配。实际上,我不知道任何编译器做了什么非常相似的事情,因此在这种情况下,仅使用buffer
和使用&buffer
之间不会有任何区别。
然而,在其他情况下,差异是可以检测到的。指针的加法和减法基于类型,因此(例如)array+1
和&array + 1
将产生不同的结果:
#include <stdio.h>
int main() {
char array[10];
printf("%p %p %p\n", array, array+1, &array+1);
return 0;
}
这将打印三个数字。第一个数字是一些任意数字,通常是十六进制数。第二个将比第一个大一个,第二个将比第一个大10(因为我将它定义为10个字符的数组......)
答案 1 :(得分:0)
至少有一个错误:
scanf("%s",&buffer);
应该是:
scanf("%s", buffer);
你正在拿指针的地址。可能不是你想要的。
编辑:
scanf也有Jerry Coffin描述的限制。
答案 2 :(得分:0)
最后我找到了解决方案!
使用gets(buffer);
scanf("%s",&buffer);
瞬间