3

我正在慢慢学习 C。我在这里阅读了有关处理字符串的输入和输出的页面:http ://www.cprogramming.com/tutorial/c/lesson9.html

在最后一个代码示例中,fgets用于获取输入变量并将其分配给 char 数组name。我尝试在自己的程序中实现类似的东西。

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

/* This is my very first C program! */

bool test=true;

/* Function Prototypes */

int mult(int x, int y);

/* Structures */

struct Person {
    int age;
    char name[256];
};

/* Complicated Array ;P */

struct Person *FirstPeriod[22];
char FakeString[100];

void PracticeStrings()
{
    int i;
    fgets(FirstPeriod[0]->name, 256, stdin);
    for (i=0;i<256;i++)
    {
            if (FirstPeriod[0]->name[i]=='\n')
                FirstPeriod[0]->name[i]='\0';
    }
    printf("\n\nHello Student 0: %s",FirstPeriod[0]->name);
}

int main()
{
    struct Person DadeLamkins;
    DadeLamkins.age=16;
    int numb;
    int x;
    int *numb_address=&numb;
    numb_address=malloc(sizeof(*numb_address));

    FirstPeriod[0]=&DadeLamkins;

    if (true)
        printf("-__- \n\n");

    printf("Please enter a number: ");
    scanf("%d", &numb);
    switch (numb) {
        case 0:
            printf("Dude, 0 is lame...\n");
            break;
        case 7:
            printf("Dude, 7 is my favorite number!\n");
            break;
        default:
            printf("You entered %d\n", numb);
            break;
    }
    for (x=0;x<numb+1;x++) {
        printf("\n::# %d",mult(x,2));
    }
    printf("\n\n%d",numb_address);
    free(numb_address);
    numb_address=0;
    PracticeStrings();
    getchar();
    return 0;
}

int mult (int x, int y)
{
    return x*y;
}

PracticeStrings26 行的函数是当前的问题。当我编译时,它会Hello Student 0: 在接受输入(来自fgets)之前显示。我正在使用 Code::Blocks 进行编译。

任何帮助,将不胜感激!

编辑...

哈哈哈,是的,我明白我的程序效率低下,很傻。如您所知,它并没有真正完成太多。它主要是推动我目前正在学习的东西并尝试应用这些东西而不实际重写代码示例(如果我逐字复制我会学到什么?)。无论如何,感谢您的帮助!我想这确实有道理!太糟糕了,我的教程没有提到这一点,我相信这只是需要一点更高的理解。我敢肯定,教程作者没想到有人会像我那样混合这些功能。

非常感谢你们!希望我能习惯这一点。我用 .net 语言编写了大量脚本和大量内容,希望我可以添加C到此列表中:)

4

2 回答 2

4

这是因为当您阅读数字时:

scanf("%d", &numb);

stdin仍然\n留在缓冲区中。因此,当您致电时PracticeStrings(),随后:

fgets(FirstPeriod[0]->name, 256, stdin);

你阅读\n并最终得到

FirstPeriod[0]->name[i] == '\0';

此外,随着您的学习,学习验证:)

IE:

if ((foo = malloc(blah)) == NULL) {
    ... err ...

更关键的是:

if (scanf(..) != number_of_items_i_want) {
    ... did not get a number, or what ever I wanted ...

等等

于 2012-04-10T00:06:50.273 回答
0

我认为你的问题是由于你的控制台的行为和你的scanf()电话。

您的控制台的默认设置可能是行缓冲。这意味着在您按下回车键之前,您在终端上键入的任何内容都不会发送到标准输入。

但是,您对scanf()(in main()) 的调用只是获取您输入的整数 - 而不是尾随回车。在第 26 行调用之前,您的回车仍在 stdin 中处于未读状态fgets()。解决此问题的一种方法是让 scanf() 也使用尾随回车:

scanf("%d%*c", &numb);
它将整数从标准输入读入&numb,并读取(并丢弃)一个额外的字符。

这一切都凸显了使用 的一个大问题scanf(),即如何在您得到一个出乎意料的字符串的情况下使其应对。更安全的方法是使用fgets()和的组合sscanf()。前者将让您从文件中读取字符串(正如您所做的那样),后者将在其上运行格式化字符串。例如。


    char temp[20];
    fgets(temp, 20, stdin);
    sscanf(temp, "%d", &numb);
于 2012-04-10T00:17:50.647 回答