计算c字符串中的单词

Counting words in a c string

本文关键字:单词 字符串 计算      更新时间:2023-10-16

我需要帮助完成这个函数,以便它正确地返回c字符串中的字数。也许我的逻辑错了?

#include <iostream>
#include <string>
#include <cctype>
int countwords(char *, int);
using namespace std;
int main()
{
    char a[] = "Four score and seven";
    int size = sizeof(a)/sizeof(char);
    cout << countwords(a,size);
    return 0;
}
int countwords(char* a, int size){
    int j = 0;
    for(int i = 0; i < size; i++){
        if(isspace(i) and isalnum(i - 1) and isalnum(i + 1))
            j++;
    }
    return j;
}

您将i的值传递给这些函数,而不是a[i]。这意味着您正在测试循环变量是否是一个空格(例如),而不是a数组中该位置的字符。

一旦你解决了这个问题,就要明白你不能在那个循环中盲目引用a[i-1](因为有可能访问a[-1]。你需要更新你的逻辑(注意,你必须使用&&进行逻辑AND,而不是and)。

我建议用一个标志来表示你目前是否"在"一个单词中。当你决定不再在一个单词中时,请重置该标志例如

int inside = 0;
for (int i = 0; i < size; i++) {
    if (alnum(a[i])) {
        if (!inside) {
            inside = 1;
            j++;
        }
    } else {
        inside = 0;
    }
}

另外,请使用strlen(a)而不是sizeof(a)/sizeof(char)。如果你继续这样的练习,总有一天当你在指针上尝试时会发生意外。

此循环是无效的

for(int i = 0; i < size; i++){
    if(isspace(i) and isalnum(i - 1) and isalnum(i + 1))

首先,您不检查字符串中的字符是空格还是字母数字。您检查变量i,whicj与字符串的内容没有任何共同之处。此外,您打算访问阵列之外的内存

当你处理字符串时,我会用以下方式声明函数

size_t countwords( const char *s );

它可以定义为

size_t countwords( const char *s )
{
    size_t count = 0;
    while ( *s )
    {
        while ( isspace( *s ) ++s;
        if ( *s ) ++count;
        wjile ( isalnum( *s ) ++s;
    }
    return ( count );
}

我不考虑标点符号。否则你应该用isspace代替!isalnum。

一个更简单的版本是对字符串重复调用strtok(),每次返回元素时,都可以增加字数。这需要加倍的空格,等等。你甚至可以毫不费力地用逗号分隔两个单词,但没有空格("This,error")。

类似的东西

do {
  s = strtok(s," ,.;");
  if (s) wordcount++;
 } while(s);

唯一直接的缺点是strtok具有破坏性,所以在开始之前先做一个副本。

要计算字数,只需要计算在空白字符后面看到非空白字符的次数。为了在字符串的开头做正确的处理,假设字符串的左边有"空白"。

int countwords(char* a, int size) {
    bool prev_ws = true;  // pretend like there's whitespace to the left of a[]
    int words = 0;
    for (int i = 0; i < size; i++) {
        // Is the current character whitespace?
        bool curr_ws = isspace( (unsigned char)a[i] ); 
        // If the current character is not whitespace, 
        // but the previous was, it's the start of a word.
        if (prev_ws && !curr_ws) 
            words++;
        // Remember whether the current character was 
        // whitespace for the next iteration.
        prev_ws = curr_ws;
    }
    return words;
}

您可能还注意到,我在对isspace()的调用中包含了对unsigned char的转换。在某些平台上,char默认为已签名,但分类器函数isspace和friends不能保证使用负值。强制所有值为正。(更多详细信息:http://en.cppreference.com/w/cpp/string/byte/isspace)