【问题标题】:Counting blanks, tabs and new line计算空格、制表符和新行
【发布时间】:2017-02-15 06:07:19
【问题描述】:

我是 C 语言的新手,谁能帮忙找出我在实现一个计算空格、制表符和换行符的程序时做错了什么。

代码:

#include <stdio.h>
//Write a program to count blanks, tabs, and newlines.
int main(){
    char str[100];
    printf("Enter the text");
    scanf("%s",&str);
    int space=0;
    int tabs=0;
    int newLine=0;
    int i=0;
    while(str[i]!='\0'){
        if (str[i] == ' ')
            space++;
        if (str[i] == '\t')
            tabs++;
        if (str[i] == '\n')
            newLine++;
        i++;

    }

    printf("space:%d\ntabs:%d\nnew line:%d",space,tabs,newLine);
    return 0;
}

【问题讨论】:

  • 如果我想从控制台而不是文件获取输入怎么办? @xing
  • 我可以使用getchar()吗?如果是,那么如何?因为我已经尝试过了,但它没有给出正确的输出
  • 谢谢@xing
  • @xing - 如果ch 应该是int 用于getchar

标签: c character


【解决方案1】:

检查这一点的更好方法是比较 ascii 值。 C 认为所有字符都在 ascii 中,就 C 而言就是这样。因此,不要将空格与空格进行比较,而是将其与 0x20(ascii 空格字符的十六进制代码)进行比较。对其他比较也这样做,它应该会好一点。

不要害怕将比较结果的打印语句发送到终端。例如,打印正在检查的字符与正在检查的字符以及结果。这将帮助您调试此处实际发生的情况。完成后不要忘记删除那些打印语句。

PS 这里是 ascii 表的链接。 http://www.asciitable.com

【讨论】:

  • 我认为比较代码不是一个好主意,因为在这种情况下,程序不能在使用 EBCDIC 表的系统中使用。
  • 大多数情况下我会同意,但 C 是 ISO 标准,这意味着如果您使用 C,那么它使用 ascii。有一些变化,因为 ascii 是限制性的,但它不是真正的 C,就像 C 一样。现在这并没有使我的解决方案变得更正确....它降低了可移植性和更糟糕的最佳实践。
  • 为什么你认为如果 C 符合 ISO 标准,那么执行标准 C 的所有系统都使用 ASCII 表?例如,IBM 大型机使用 EBCDIC 表。
【解决方案2】:

如果您想进行控制台输入(如 cmets 中的 @xing 所说),您应该使用 fgets 而不是 scanf。所以我们应该有:

#define SIZE_MAX 255

int main() {
    char str[SIZE_MAX];
    int i;
    int space;
    int tabs;

    printf("Enter the text : ");
    fgets(str, SIZE_MAX, stdin);    //stdin if it is a console input
    // Careful, if the input length is shorter than the SIZE_MAX (here 255),
    // Then a '\n' will be added at the end of your string. To counter it :
    if(strchr(str, '\n') != 0) {    //checks if there is a '\n'
        str[strlen(str)-1] = '\0';  //changes it to a '\0' (end of string)
    }

    //For the verifications, you can do that :
    for(i=0 ; i < strlen(str) ; i++) {
        if (str[i] == ' ') {
            space++;
        }
        if (str[i] == '\t') {
            tabs++;
        }
    }
    printf( "\nspace : %d\ntabs: %d\n", space, tabs);

    //NB : There will be no newLine because it is a console input.
    return 0;
}

【讨论】:

  • @nsonore 在这种情况下如何计算换行符?:)
  • 好吧,不会有新的行数了。当用户按下输入时,它会验证输入。据我所知,使用控制台输入时不能添加 '\n' 。但是,如果它是您要读取的文件,那么 fgets 将读取到下一个新行,因此您只需为其创建一个计数器。
【解决方案3】:

在您的程序中使用的scanf 函数不安全,并且不允许计算空格。


笔记。考虑到,而不是
scanf("%s",&str);
          ^^^ 

这样写就对了

scanf("%s",str);
          ^^^

并且根据 C 标准,不带参数的函数 main 应声明为

int main( void )

最好使用函数fgetc

例如

#include <stdio.h>

int main(void) 
{
    unsigned int space = 0;
    unsigned int tabs = 0;
    unsigned int newLine = 0;

    printf( "Enter the text: " );

    int c;

    while ( ( c = fgetc( stdin) )  != EOF )
    {
        switch ( c )
        {
        case ' ':
            ++space;
            break;

        case '\t':
            ++tabs;
            break;

        case '\n':
            ++newLine;
            break;
        }
    }

    printf( "\nspace: %u\ntabs: %u\nnew line: %u\n", space, tabs, newLine );

    return 0;
}

如果要输入这样的文字

Hi, Marco Roberts 
Welcome to SO

那么程序输出会是这样的

space: 4
tabs: 0
new line: 2

使用 Ctrl + z 或 Ctrl + d(取决于使用的系统)中断输入。

另一种方法可以如下所示

#include <stdio.h>

#define N   100

int main(void) 
{
    unsigned int space = 0;
    unsigned int tabs = 0;
    unsigned int newLine = 0;

    printf( "Enter the text: " );

    char str[N];

    while ( fgets( str, sizeof( str ), stdin ) )
    {
        for ( const char *p = str; *p; ++p )
        {
            switch ( *p )
            {
            case ' ':
                ++space;
                break;

            case '\t':
                ++tabs;
                break;

            case '\n':
                ++newLine;
                break;
            }
        }           
    }

    printf( "\nspace: %u\ntabs: %u\nnew line: %u\n", space, tabs, newLine );

    return 0;
}

【讨论】:

    猜你喜欢
    • 2011-03-14
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-04
    • 2017-03-08
    • 1970-01-01
    • 2021-08-01
    相关资源
    最近更新 更多