虽然第二次访问循环时第一次循环不起作用

时间:2018-01-11 00:15:39

标签: c while-loop

好的,我已经运行了4次功能。它第一次完美运行,但是当我必须再次运行该功能时,我得到" * INVALID ENTRY * :"当用户没有输入' y'或者' Y'或者' n'或者' N' 此外,我试图使其无论何时用户输入"是或否"它会提示"错误信息"但目前我编写程序的方式只需要用户的第一个字符"例如:输入"是"该计划只会采用" Y"这使程序认为用户输入了“Y'这会跳过错误阶段。

这就是我的主要内容

printf("Please enter 'Y' > ");
printf("    Result: %d\n", yes() );
printf("Please enter 'y' > ");
printf("    Result: %d\n", yes());
printf("Please enter 'N' > ");
printf("    Result: %d\n", yes());
printf("Please enter 'yes', then 'no', then 'n' > ");
printf("    Result: %d\n", yes());

这是我试图访问的部分。

int yes(void) {
    char singleLetter;
    int theResults = 0;
    scanf("%c", &singleLetter);
    while ((singleLetter != 'y') && (singleLetter != 'Y') && (singleLetter != 'n') && (singleLetter != 'N')) {


                clearKeyboard();
                printf("*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: ");
                scanf("%c", &singleLetter);

        } 

        if ((singleLetter == 'y') || (singleLetter == 'Y')) {
            theResults = theResults++;
        }
        if ((singleLetter == 'n') || (singleLetter == 'N')) {
            theResults = 0;
        }
        //printf("%c",singleLetter);
    return theResults;
}

结果是:

Please enter 'Y' > Y
    Result: 1
Please enter 'y' > y
*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: y
    Result: 1
Please enter 'N' > N
*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: N
    Result: 0
Please enter 'yes', then 'no', then 'n' > yes
*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: no
    Result: 0

EDIT :: 我修复了上面的代码,所以它工作正常 但是,当我从一个不同的函数调用yes()时,我收到此错误: 这是我试图调用的代码:

void getName(struct Name *contactName) {

    printf("Please enter the contact's first name: ");
    scanf("%s", (*contactName).firstName);
    printf("Do you want to enter a middle intial(s)? (y or n): ");
    yes();

    if (yes() == 1) {
        printf("Please enter the contact's middle intial(s): ");
        scanf("%s", (*contactName).middleInitial);

    }

    printf("Please enter the contact's last name: ");
    scanf("%s", (*contactName).lastName);
}

我用

修复了yes()代码
int yes(void) {
    char singleLetter;
    int theResults = 0;
    scanf("%c", &singleLetter);
    clearKeyboard();

    while ((singleLetter != 'y') && (singleLetter != 'Y') && (singleLetter != 'n') && (singleLetter != 'N')) {

                printf("*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: ");
                scanf("%c", &singleLetter);
                clearKeyboard();

        } 

        if ((singleLetter == 'y') || (singleLetter == 'Y')) {
            theResults = theResults + 1;
        }
        if ((singleLetter == 'n') || (singleLetter == 'N')) {
            theResults = 0;
        }

    return theResults;
}

我收到此错误。字面上让我输入了3次,并且我无缘无故地得到了无效的输入代码。

Do you want to enter a middle intial(s)? (y or n): y
*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: y
y
Please enter the contact's middle intial(s):

编辑第2部分 我通过这样做修复了我的函数yes():

int yes(void) {
        char singleLetter = ' ';  
        int finalValue = -1; 
        int theResult = 0; 

        scanf(" %c", &singleLetter);
        clearKeyboard();

        do
        {
            switch (singleLetter)
            {

            case 'Y':
            case 'y':
                finalValue = 1;
                theResult = 1;
                break;

            case 'N':
            case 'n':
                finalValue = 0;
                theResult = 1;
                break;
            default:
                theResult = 0;
                printf("Only (Y)es or (N)o are acceptable: ");
                scanf("%c", &singleLetter);
                clearKeyboard();
            }
        } while (!theResult);

        return finalValue;

    }

这是代码,我不确定该代码的结尾:

void getName(struct Name *contactName) {

            printf("Please enter the contact's first name: ");
            scanf("%s", (*contactName).firstName);
            printf("Do you want to enter a middle intial(s)? (y or n): ");

            if (yes() == 1) {
                printf("Please enter the contact's middle intial(s): ");
                scanf("%s", (*contactName).middleInitial);

            }

            printf("Please enter the contact's last name: ");
            scanf("%s", (*contactName).lastName);
        }

        // getAddress:
        void getAddress(struct Address *

contactAddress) {


        printf("Please enter the contact's street number: ");

        (*contactAddress).streetNumber == getInt();

        printf("Please enter the contact's street name: ");
        scanf(" %[^\n]", (*contactAddress).street);

        printf("Do you want to enter an apartment number? (y or n): ");

        if (yes() == 1) {
            printf("Please enter the contact's apartment number: ");
            scanf("%d", (*contactAddress).apartmentNumber);
        }

        printf("Please enter the contact's postal code: ");
        scanf(" %[^\n]", (*contactAddress).postalCode);
        printf("Please enter the contact's city: ");
        scanf("%s", (*contactAddress).city);
    }

    // getNumbers:


    // getNumbers:
    // NOTE:  Also modify this function so the cell number is
    //        mandatory (don't ask to enter the cell number)
    void getNumbers(struct Numbers *contactNumber) {

        printf("Please enter the contact's cell phone number: ");
        scanf(" %s", (*contactNumber).cell);
        printf("Do you want to enter a home phone number? (y or n) ");

        if (yes() == 1) {
            printf("Please enter the contact's home phone number: ");
            scanf("%s", (*contactNumber).home);
        }

        printf("Do you want to enter a business number? (y or n) ");

        if (yes() == 1) {
            printf("Please enter the contact's business phone number: ");
            scanf("%s", (*contactNumber).business);
        }
        printf("\n");
    }

AND BELOW THAT I HAVE THIS AND DONT KNOW WHAT TO DO. AS I STATED IN THE COMMENT:
  

此功能的目的是设置联系人使用的值   指针参数变量(设置它指向的联系人)。

     

使用接收到此功能的指针参数来提供相应的参数   联系成员到“get”函数(getName,getAddress和getNumbers)来设置联系人的值。

    void getContact(struct Contact *contact) {
        getName(contact);
        getAddress(contact);
        getNumbers(contact);
    }

BELLOW是什么东西被访问/打印。无论我输入什么,它都不会出现因为void getContact(struct Contact * contact){}

 getContact(&contact);
    printf("\nValues Entered:\n");
    printf("Name: %s %s %s\n", contact.name.firstName, contact.name.middleInitial, contact.name.lastName);
    printf("Address: %d|%s|%d|%s|%s\n", contact.address.streetNumber, contact.address.street, 
        contact.address.apartmentNumber, contact.address.postalCode, contact.address.city);
    printf("Numbers: %s|%s|%s\n", contact.numbers.cell, contact.numbers.home, contact.numbers.business);

1 个答案:

答案 0 :(得分:0)

scanf在换行符中保留换行符\n,下次执行scanf时,会读取换行符。考虑一下这个程序:

#include <stdio.h>

int main(void)
{
    char x;
    scanf("%c", &x);

    printf("%d: '%c'\n", x, x);
    scanf("%c", &x);
    printf("%d: '%c'\n", x, x);

    return 0;
}

输入w<ENTER>s<ENTER>

的输出
w
119: 'w'
10: '
'

在ASCII 119中,'w'是10,'\n'

如果您在getchar()之后添加scanf,那么getchar()会读取换行符 然后在缓冲区中没有任何内容,然后下一个scanf再次等待用户输入:

#include <stdio.h>

int main(void)
{
    char x;
    scanf("%c", &x);
    getchar();  // <-- look here

    printf("%d: '%c'\n", x, x);
    scanf("%c", &x);
    printf("%d: '%c'\n", x, x);

    return 0;
}

我得到的输入相同

w
119: 'w'
s
115: 's'

因此,要解决您的问题,您可以在getchar()之后添加scanf

使用scanf后清除缓冲区的最佳方法:

int c;
while((c = getchar() !='\n') && c !=EOF );

修改

如何使用fgets

  

man fgets

#include <stdio.h>

char *fgets(char *s, int size, FILE *stream);
     

fgets()最多从size读取一个少于stream个字符并将其存储到缓冲区中   由s指出。读数在EOF或换行符后停止。如果读取换行符,则将其存储到   缓冲区。终止空字节('\0')存储在缓冲区中的最后一个字符之后。

只需获得一行,即可:

char line[1024];
fgets(line, sizeof line, stdin);
当没有更多行要阅读或有一行时,

fgets将返回NULL 错误。无论哪种方式发生这种情况,您通常都会停止阅读该文件。那是 为什么要读取文件中的所有行(或用户的多行),你这样做 这样:

char line[1024];
while(fgets(lines, sizeof line, stdin))
{
    // do the work here
}

请记住,当sizeof linefgets时,linemalloc只是正确的 阵列。例如,如果您使用sizeof line分配内存,则无法使用 size_t n = <some value>; // the value is not imporant, // could be 100, could be 985 char *line = malloc(n); if(line == NULL) { // error handling, for example return error value } // only if line is not NULL fgets(line, n, stdin); // here I know the size in advance // or as argument void foo(char *buffer, size_t size) { fgets(buffer, size, stdin); ... } 。如果你得到一个指针,那么你必须提前知道多少 你可以阅读。

char line[1024];
fgets(line, sizeof line, stdin);

int len = strlen(line);
if(line[len - 1] == '\n')
    line[len - 1] = 0;

如果线的长度小于缓冲区的大小(减1),则 换行符将存储在缓冲区中。如果你不需要它,你可以 将其设置为0以摆脱换行符:

yes

但如果您不介意使用换行符,那么您不必这样做。

因此,您可以使用fgets编写#include <ctype.h> int yes(void) { int theResults = 0; char line[1024]; if(fgets(line, sizeof line, stdin) == NULL) { fprintf(stderr, "could not get line, aborting\n"); return -1; // error value } while(toupper(line[0]) != 'Y' && toupper(line[0]) != 'N') { printf("*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: "); if(fgets(line, sizeof line, stdin) == NULL) { fprintf(stderr, "could not get line, aborting\n"); return -1; // error value } } if(toupper(line[0]) == 'Y') theResults++; else theResults = 0; return theResults; } 函数。甚至可以获得整条生产线 如果你只对第一个角色感兴趣,你可以忽略其余部分 行中的字符。

getElement