【问题标题】:String won't store more than one word (C)字符串不会存储超过一个单词 (C)
【发布时间】:2020-07-17 18:07:43
【问题描述】:

这是我编写的程序的第一步。

目标:用户需要写一个句子,我的程序需要将它存储在一个数组中。这可以是他们喜欢的短或长。

我的程序:运行没有技术错误

问题:当我运行程序时,我无法提交超过 1 个单词的内容。 'Hello' 提交并且程序执行。除此之外的任何东西 - 新单词、空格、标点符号和数字,当我按 Enter 键时 - 我只是不断跳到终端中的新行,程序不会进入下一步。

这是我正在使用的代码

  1. 提示用户输入文本和
  2. 存储答案。
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
    
int main(void)
{
    string z = get_string("Text: \n");
    
    //  int n = strlen(z);
    
    int a = 0;
    int d = 1;
    int e = 0;
    
    while (z[a] != '\0')
    {
        while (isalpha(z[a]))
        {
            a++;
        }
    
        while (z[a] ==' ')
        {
            d++;
        }
    
        //Count the sentences
    
        while (z[a] == '.' || z[a] == '!' || z[a] == '?' || z[a] == '/')
        {
            e++;
        }
    }
    
    // printf("%i letter(s)\n", a);
    // printf("%i word(s)\n", d);
    // printf("%i sentence(s)\n", e);
    
    //Coleman-Liau index formula
    
    int m = (0.0588 * (100 * a / d) - 0.206 * (100 * e / d) - 15.8);
    
    if (m <= 1)
    {
        printf("Before Grade 1\n");
    }
    
    if (m >= 16)
    {
        printf("Grade 16+\n");
    }
    
    if (m < 16)
    {
        printf("Grade %i\n", m);
    }
}

非常新的编码和任何帮助将不胜感激!

我的终端截图

【问题讨论】:

  • 那是 CS50 get_string() 还是你写的函数?
  • 什么是不起作用的“下一步”?
  • 我不确定你的意思。当您按 Enter 时,它应该会转到终端中的新行。将printf("%s\n", z); 放在该行之后,您应该会看到您输入的行。
  • 欢迎来到 SO。您可以轻松地将终端中的纯文本复制并粘贴到您的问题中。无需制作屏幕截图并将输出添加为图形。
  • while (z[a] ==' ') { d++;如果 z[a] == ' ',} 将永远不会停止

标签: arrays c string cs50


【解决方案1】:

问题在于计算单词和句子的while循环永远不会增加a,这是z的索引。所以他们一遍又一遍地测试同一个角色,你就陷入了无限循环。

它适用于单个单词,因为这些测试从一开始就不会成功。

您也不应该使用将字母计数为数组索引的变量。

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
    
int main(void)
{
    
    char *z = get_string("Text: \n");
    
    //  int n = strlen(z);
    
    int i = 0;
    int a = 0;
    int d = 1;
    int e = 0;
    
    while (z[i] != '\0')
    {
        int counted = 0;
        while (isalpha(z[i]))
        {
            a++;
            i++;
            counted = 1;
        }
    
        while (z[i] ==' ')
        {
            d++;
            i++;
            counted = 1;
        }
    
        //Count the sentences
    
        while (z[i] == '.' || z[i] == '!' || z[i] == '?' || z[i] == '/')
        {
            e++;
            i++;
            counted = 1;
        }
        if (!counted) {
            i++;
        }
    }
    
    // printf("%i letter(s)\n", a);
    // printf("%i word(s)\n", d);
    // printf("%i sentence(s)\n", e);
    
    //Coleman-Liau index formula
    
    int m = (0.0588 * (100 * a / d) - 0.206 * (100 * e / d) - 15.8);
    
    if (m <= 1)
    {
        printf("Before Grade 1\n");
    }
    
    if (m >= 16)
    {
        printf("Grade 16+\n");
    }
    
    if (m < 16)
    {
        printf("Grade %i\n", m);
    }
}

【讨论】:

  • while (z[i] != '\0') 循环永远不会嵌套 3 个 while 循环进入。
  • 很好,我添加了一个变量来检查这种情况。
【解决方案2】:

以下建议的代码:

  1. 干净地编译使用:gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled2.c" -o "untitled2.o"
  2. 执行所需的功能
  3. 使用有意义的变量名
  4. 使用唯一的变量名来单步调试文本
  5. 不包括那些内容没有使用的头文件
  6. 使用for() 循环遍历文本
  7. 使用size_t 而不是int 变量,因为这些变量的内容永远不会是

现在建议的代码:

#include <cs50.h>
#include <stdio.h>
//#include <string.h>
//#include <math.h>
#include <ctype.h>
    
int main(void)
{
    string z = get_string("Text: \n");
    
    size_t spaces = 0;
    size_t sentences = 0;
    size_t letters = 0;
    
    for( size_t i = 0; z[i]; i++ )
    { 
        if( z[i] ==' ' )
        {
            spaces++;
        }
        
        if( isalpha( z[i] ) )
        {
            letters++;
        }
    
        //Count the sentences
    
        if( z[i] == '.' || z[i] == '!' || z[i] == '?' || z[i] == '/')
        {
            sentences++;
        }
    }
    
    // printf("%i letter(s)\n", a);
    // printf("%i word(s)\n", d);
    // printf("%i sentence(s)\n", e);
    
    //Coleman-Liau index formula
    
    int m = (int)(0.0588 * (double)(100 * letters / spaces) - 0.206 * (double)(100 * sentences / spaces) - 15.8);
    
    if (m <= 1)
    {
        printf("Before Grade 1\n");
    }
    
    if (m >= 16)
    {
        printf("Grade 16+\n");
    }
    
    if (m < 16)
    {
        printf("Grade %i\n", m);
    }
}

程序的典型运行:

Text: 
a quick brown fox jumped over a lazy dog
Grade 7

【讨论】:

    【解决方案3】:

    您可以简单地使用fgets() 来接受所有内容,直到换行符和strchr() 的一点帮助来删除换行符:

    #define MAX_LENGTH 1024
    
    char z[MAX_LENGTH];
    fgets(z, MAX_LENGTH, stdin);
    
    z[strlen(z) - 1] = '\0';
    

    最好使用条件语句而不是循环:

    int i = 0;
    
    while (z[i++]) {
        if (isalpha(z[i]))
            a++;
    
        if (z[a] == ' ')
            d++;
    
        if (z[i] == '.' || z[i] == '!' || z[i] == '?' || z[i] == '/')
            e++;
    }
    

    【讨论】:

    • get_string() 自动分配字符串,因此您不必指定最大长度。它还会自动删除换行符,您不会这样做。
    • @Barmar 我一直使用标准 C。这就是原因。答案已更新,现在删除了换行符。
    • 发布的答案使用i 单步执行文本,但使用a 进行测试。这意味着a 将查看当前测试字符以外的字符。 IE。这个答案不会产生正确的结果
    • @user3629249 更新了答案。感谢您指出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 2013-05-07
    • 1970-01-01
    • 2017-01-22
    • 1970-01-01
    • 2013-12-01
    相关资源
    最近更新 更多