【问题标题】:Scanning from user input in a for loop [duplicate]在for循环中从用户输入进行扫描[重复]
【发布时间】:2014-01-18 13:41:20
【问题描述】:

我正在尝试在 for 循环中扫描用户输入,除了循环的第一次迭代之外,它需要 2 条数据才能继续下一步,我不明白为什么。我将在下面展示我的代码,但作为提醒,我对此真的很陌生而且不是很好,我什至不确定我使用的方法是否最有效。

#include    <stdlib.h>
#include    <stdio.h>
#include    <math.h>

#define     w   1.0
#define     R   1.0

int main(int argc, char *argv[])
{
int     tmp;
double  *x, *v, *m, *k;

x = malloc((argc-1)*sizeof(double));
v = malloc((argc-1)*sizeof(double));
m = malloc((argc-1)*sizeof(double));
k = malloc((argc-1)*sizeof(double));

if(x != NULL)
{
    for(tmp=0; tmp<argc-1; tmp++)
    {
        sscanf(argv[tmp+1], "%lf", &x[tmp]);
    }
}
else
{
    printf("**************************\n");
    printf("**Error allocating array**\n");
    printf("**************************\n");
}

if(argc <= 2)
{
    printf("************************************\n");
    printf("**There must be at least 2 masses!**\n");
    printf("************************************\n");
}
else if(argc == 3)
{
    for(tmp=0; tmp<argc-1; tmp++)
    {
        printf("Input a value for the velocity of Block %d\n", tmp+1);
        scanf("%lf\n", &v[tmp]);
    }

    for(tmp=0; tmp<argc-1; tmp++)
    {
        printf("Input a value for the mass of Block %d\n", tmp+1);
        scanf("%lf\n", &m[tmp]);
    }

    for(tmp=0; tmp<argc-1; tmp++)
    {
        printf("Input a value for the spring constant of Spring %d\n", tmp+1);
        scanf("%lf\n", &k[tmp]);
    }
}
else
{
    for(tmp=0; tmp<argc-1; tmp++)
    {
        printf("Input a value for the velocity of Mass %d\n", tmp+1);
        scanf("%lf\n", &v[tmp]);
    }

    printf("Input a value for the mass of each Block\n");
    for(tmp=0; tmp<argc-1; tmp++)
    {   
        scanf("%lf\n", &m[tmp]);
    }

    printf("Input a value for the spring constant of each Spring\n");
    for(tmp=0; tmp<argc-1; tmp++)
    {
        scanf("%lf\n", &k[tmp]);
        printf("%lf\n", &k[tmp]);
    }
}   
}

所以是的,主要问题是当为块 1 的速度取一个值时,它需要两个值

【问题讨论】:

  • scanf("%lf%*c",&v[temp]);可以解决问题。
  • 是的,你是对的,我猜是我没有彻底检查旧帖子!

标签: c


【解决方案1】:

删除每种格式后的空白"\n"

// scanf("%lf\n", &v[tmp]);
scanf("%lf", &v[tmp]);

"\n""%lf" 之后的空白空间scanf() 指示scanf() 继续扫描和使用空白空间(例如' ''\n''\t''\r' 和其他 4 个)直到找到非空白char。这将消耗 Enter'\n' 寻找更多的空白。

由于stdin 通常是缓冲的,因此需要输入整个下一行,然后scanf("\n") 才能看到它。

一旦scanf("\n") 遇到非空白,它会将其放回stdin 以进行下一个 I/O 操作。


scanf() 通常会在输入错误输入时提出挑战。对于恶意用户输入的稳健处理,请考虑使用fgets()/sscanf() 组合。 (或fgets()/strtod()

char buf[50];
double d;
if (fgets(buf, sizeof buf, stdin) == NULL) Handle_EOForIOError();
if (sscanf(buf, "%d", &d) != 1) Handle_ParseError();
// good to go

以下内容确实使用了double 之后的字符,这通常是 Enter,但会产生错误句柄挑战,应该像“1.23.45”这样的输入发生。

// scanf("%lf\n", &m[tmp]);
scanf("%lf%*c", &m[tmp]);  // Not recommended.

无论采用何种代码路径,检查scanf()/sscanf()/fcanf() 的结果总是一个好主意,尤其是在阅读double 时。


空白指令" ""\n""\t" 等都表现相同。格式字符串中的任何空白指令都会使用任何空白。

// All work the same.    
scanf("%lf\n", &v[tmp]);
scanf("%lf\t", &v[tmp]);
scanf("%lf ", &v[tmp]);

【讨论】:

    猜你喜欢
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多