scanf()和gets()的意外行为

时间:2014-03-07 11:55:08

标签: c file scanf gets

我想一次性写一行(包括空格)到以下代码: -

//in main
char ch[40];
FILE *p;
char choice;
p=fopen("textfile.txt","w");
printf("%s\n","you are going to write in the first file" );
while (1)
{
    gets(ch);// if i use scanf() here the result is same,i.e,frustrating
    fputs(ch,p);
    printf("%s\n","do you want to write more" );
    choice=getche();
    if (choice=='n'|| choice=='N')
    {
        break;
    }
}

上述代码的结果令我感到沮丧,很难解释。但我仍会尝试。 如果我输入,比方说,

"my name is bayant." 

然后按回车状态进入屏幕

"do you want to write more"

直到现在它都很好,但是当我提出除'n'或'N'之外的其他键(根据程序逻辑要求写更多行)然后消息

"do you want to write more"

再次打印。现在如果我按下“n”或“N”之外的其他键,则在屏幕上打印相同的行。按照此步骤打印语句

"do you want to write more"

4次,这是单词的数量,即在这种情况下为4。通过这个不灵活的程序,我在我的文件上得到了所需的行,但是如果是对第一次打印语句的反应

"do you want to write more"

我按'n'或'N'然后只有第一个单词,即在这种情况下“my”打印在文件上。 那么一次性在文件上写一个完整的行的解决方案是什么?为什么在这种情况下gets()和fputs()似乎无效? 提前超过xxx。

2 个答案:

答案 0 :(得分:2)

做这样的事情,这是一个非常粗糙的计划,但应该给你一个想法

你的错误,你只是在你的程序中创建了一个指向char的指针,你需要使用malloc为指针分配内存,或者另一个选项就是创建一个chars数组。我已经完成了。

#include <stdio.h>
#include <stdlib.h>
int main(void){

char ch[100];
FILE *p;
char choice;
p=fopen("textfile.txt","w");
printf("%s\n","you are going to write in the first file" );
while (1)
{
// gets(ch);// if i use scanf() here the result is same,i.e,frustrating
int c =0;

fgets(ch,100,stdin);
fputs(ch,p);
printf("%s\n","do you want to write more" );
choice=getchar();
if (choice=='n'|| choice=='N')
    {
    break;
    }
while ((c = getchar()) != '\n' && c != EOF);
}
return 0;
}

你的程序正在重复printf("%s\n","do you want to write more" );,因为输入缓冲区有一个\ n写入它,你需要在读取之前清除缓冲区。此行从缓冲区while ((c = getchar()) != '\n' && c != EOF);

中删除换行符

检查一下 scanf() leaves the new line char in buffer?

答案 1 :(得分:2)

如果您使用

scanf("%s",ch);

(我假设你的意思是“scanf”),这将读取一个字符串。如果您输入

  

“我的名字很棒。”

这将产生4个字符串:“my”,“name”,“is”和“bayant”。

请注意,根据您的描述,您不想阅读字符串,您想要阅读。要使用scanf读取整行文本,您可以使用:

scanf("%[^\n]", ch);
scanf("%*c");

这意味着: 第1行:“读取所有内容,直到找到\ n字符”。

第2行:“读取并忽略'\ n'字符(留在缓冲区中)”。

我应该说这不是一个安全的解决方案,因为用户可以轻松地溢出“ch”缓冲区,但我相信如果在您的特定情况下这是一个真正的问题,您可以找到更好的方法来做到这一点。