【问题标题】:Strings, gets and do while字符串,gets 和 do while
【发布时间】:2013-02-26 17:35:57
【问题描述】:

我正在用 C 语言做一个练习,但我有一个问题,我想重复 cicle (do while),事实上,如果我输入 1,程序会从顶部重新开始,但它不会停止在gets(testo);。我尝试了很多方法来解决这个错误但没有解决方案,有人可以帮助我吗?

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

main(){
        int cch, cw, i, j, w, ord, f; //counter and index
        char testo[80];
        char alfa[50][25];
        char swap[25];

        do{     
                cch=0;
                cw=0;
                j=0;
                w=0;
                f=0;

                for(i=0;i<80;i++){
                        testo[i]='\0';
                }
                printf("Write the text:\n");
                gets(testo);

                //initialization 2d array
                for(i=0;i<50;i++){
                        for(j=0;j<25;j++){
                                alfa[i][j]='\0';
                        }
                }

                j=0;
                //Count word and characters
                if(testo[0]!='\0'){
                        cw=1;   
                        for(i=0;testo[i]!='\0';i++){
                                cch++;
                                if(testo[i]==' '){
                                        cw++;
                                        j++;
                                }
                        }
                }

                if(cch==j){
                        printf("You haven't written any word\n\n");
                }
                else{
                        //Don't count double space
                        for(i=0;i<cch;i++){
                                if(testo[i]==' ' && testo[i+1]==' '){
                                        cw--;
                                }
                        }

                        //Don't count as word if the text start with a space
                        if(testo[0]==' '){
                                cw--;
                                w--;
                        }

                        printf("\nThe text is composed by %d characters\n", cch);
                        printf("The text is composed by %d words\n", cw);

                        if(cw>0){
                                printf("\nUsed words:\n");
                                for(j=0;j<cch;j++){
                                        if(testo[j]==' ' && testo[j+1]==' '){
                                                //nothing to do        
                                        }
                                        else{
                                                if(testo[j]!=' '){
                                                        alfa[w][f]=testo[j];
                                                        f++;
                                                }
                                                else if(testo[j]=='\0'){
                                                        alfa[w][f]='\0';
                                                        f=0;
                                                        w=0;
                                                }
                                                else{
                                                        alfa[w][f]='\0';
                                                        w++;
                                                        f=0;
                                                }
                                        }
                                }

                                for(i=0;i<cw;i++){
                                        printf("%d> %s\n", i+1, &alfa[i]);
                                }

                                //order
                                f=1;
                                printf("\nWords used in alphabetical order:\n");
                                while(f==1){
                                        f=0;
                                        for(i=0;i<cw-1;i++){
                                                ord=strcmp(alfa[i],alfa[i+1]);
                                                if(ord>0){
                                                strcpy(swap,alfa[i]);
                                                strcpy(alfa[i],alfa[i+1]);
                                                strcpy(alfa[i+1],swap);
                                                f=1;
                                                }       
                                        }
                                }

                                for(i=0;i<cw;i++){
                                        printf("%d> %s\n", i+1, alfa[i]);
                                }
                        }
                }

        printf("\nDo you want write another text? (1=yes) -> ");
        scanf("%d", &j);

        }while(j==1);
}

我知道目前作为代码并没有得到很好的优化并且还有其他错误,但是我在这方面遇到了问题。

谢谢。

PS:代码在OpenVMS上测试

【问题讨论】:

    标签: c string gets openvms


    【解决方案1】:

    这是因为循环末尾的scanf 调用没有读取换行符。相反,您的gets 调用会读取此换行符。

    一个简单的解决方案是在scanf 格式字符串的末尾添加一个空格,如下所示:

    scanf("%d ", &j);
    

    这将使scanf 在输入中跳过尾随空格。

    另一种解决方案是在scanf 之后多加一个fgets,但是不要在格式字符串中添加额外的空格:

    scanf("%d", &j);
    fgets(testo, sizeof(testo), stdin);
    

    或者使用fgets获取线路,然后使用sscanf提取答案:

    fgets(testo, sizeof(testo), stdin);
    sscanf(testo, "%d", &j);
    

    【讨论】:

    • 如果我放了空格,当我执行程序时一切正常,但之后我输入 1 e 回车,写入文本不显示。
    • 如果我输入 2 后我必须再次输入(两次)
    • @AlessioMTX 我不确定我是否理解你的意思?
    • 要退出程序,我必须输入一个不同于 1 的数字,所以我输入 2,我按 enter 但我必须输入两次才能终止程序
    • @JoachimPileborg:这正是gets() 对人们所做的事情,以及为什么必须避免这样做。 ;-)
    【解决方案2】:

    或者你可以尝试在gets()之前使用函数flushall()

    【讨论】:

    • flushall 给我错误:在此语句中,标识符“flushall”被隐式声明为函数。我需要使用/添加另一个头文件吗?
    • 嗯,不。它适用于 TC 和 VS。我不确定 OpenVMS
    • 现在我搜索类似在 OpenVMS 上使用的东西
    【解决方案3】:

    您的第一个也是最明显的问题是左侧换行符。当你在这里使用scanf() 时:

        printf("\nDo you want write another text? (1=yes) -> ");
        scanf("%d", &j);
    }
    

    并且您使用%d 格式规范,该功能正在寻找一个数字,当您输入一个数字时,您实际上是在输入一个数字和一个换行符

    > 1<enter key>   // which means on stdin you're getting   '1''\n'
    

    scanf() 只拾取 1 并离开您的 gets() 函数然后拾取的换行符,因此看起来它正在跳过输入。您需要做的就是使用该换行符,一种快速解决方法是使用getchar() 使用它:

        printf("\nDo you want write another text? (1=yes) -> ");
        scanf("%d", &j);
        getchar();
    }
    

    现在您的程序可以按预期运行。


    其他注意事项:

    1. 你的 main 应该返回一个 int 类型,即使它只是一个 return 0
    2. 你不应该使用gets(),即使man page 表示gets()永远不要使用gets()。这通常是一个很好的暗示。 ;) 所以用fgets(testo, sizeof(testo), stdin); 替换那行
    3. 你在这里错过了一个性能指标:printf("\nThe text is composed by % characters\n", cch); 所以你得到了垃圾输出,应该是%d

    【讨论】:

    • 谢谢,我要试试。对于第三点,我忘记在翻译过程中输入 %d ;)
    • @AlessioMTX - 是的,我认为丢失的%d 是翻译中忘记的东西,似乎很明显被遗漏了。祝它工作顺利,如果您有任何后续问题,请告诉我。咻。
    • @AlessioMTX 很高兴为您提供帮助! :D
    猜你喜欢
    • 1970-01-01
    • 2014-04-26
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 2013-12-01
    • 2016-05-26
    • 1970-01-01
    相关资源
    最近更新 更多